310 likes | 520 Views
Stat mmap and file system interface. Nezer J. Zaidenberg. Stat(2). NAME stat, lstat, fstat -- get file status SYNOPSIS #include <sys/types.h> #include <sys/stat.h> int stat(const char *path, struct stat *sb); int lstat(const char *path, struct stat *sb);
E N D
Stat mmap and file system interface Nezer J. Zaidenberg
Stat(2) NAME stat, lstat, fstat -- get file status SYNOPSIS #include <sys/types.h> #include <sys/stat.h> int stat(const char *path, struct stat *sb); int lstat(const char *path, struct stat *sb); int fstat(int fd, struct stat *sb);
Struct stat (1/2)) struct stat { dev_t st_dev; /* device inode resides on */ ino_t st_ino; /* inode's number */ mode_t st_mode; /* inode protection mode */ nlink_t st_nlink; /* number or hard links to the file */ uid_t st_uid; /* user-id of owner */ gid_t st_gid; /* group-id of owner */ dev_t st_rdev; /* device type, for special file inode */
Struct stat (2/2) struct timespec st_atimespec; /* time of last access */ struct timespec st_mtimespec; /* time of last data modification */ struct timespec st_ctimespec; /* time of last file status change */ off_t st_size; /* file size, in bytes */ quad_t st_blocks; /* blocks allocated for file */ u_long st_blksize;/* optimal file sys I/O ops blocksize */ u_long st_flags; /* user defined flags for file */ u_long st_gen; /* file generation number */ };
Unlink(2) NAME unlink -- remove directory entry SYNOPSIS #include <unistd.h> int unlink(const char *path);
Lseek(2) NAME lseek -- reposition read/write file offset SYNOPSIS #include <unistd.h> off_t lseek(int fildes, off_t offset, int whence);
Creat(2) SYNOPSIS #include <fcntl.h> int creat(const char *path, mode_t mode);
Dup(2) SYNOPSIS #include <unistd.h> int dup(int oldd); int dup2(int oldd, int newd);
Flock(2) SYNOPSIS #include <sys/file.h> #define LOCK_SH 1 /* shared lock */ #define LOCK_EX 2 /* exclusive lock */ #define LOCK_NB 4 /* don't block when locking */ #define LOCK_UN 8 /* unlock */ int flock(int fd, int operation);
Fcntl(2) SYNOPSIS #include <fcntl.h> int fcntl(int fd, int cmd, int arg);
Linking • Symlink(2) • Link(2) • Create soft and hard link
Memory mapping • Mmap(2) • Munmap(2) • Msync(2)
Mmap(2) • Copy a file to memory • This memory can be shared (among process) or locked • Check mprotect(2) for locking option (beyond our scope) • Use msync(2) to write changes • Use munmap(2) to write and free memory • Homework : use read(2) and write(2) to copy file. Then use mmap and memory copy. What works faster?
Mmap(2) NAME mmap -- map files or devices into memory SYNOPSIS #include <sys/mman.h> void * mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t offset);
Munmap(2) NAME munmap -- remove a mapping SYNOPSIS #include <sys/mman.h> int munmap(void *addr, size_t len);
Msync(2) NAME msync -- synchronize a mapped region SYNOPSIS #include <sys/mman.h> int msync(void *addr, size_t len, int flags);
Example (1/2) #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> /* mmap() is defined in this header */ #include <fcntl.h> int main (int argc, char *argv[]) // will be used as cp source dest { int fdin, fdout; char *src, *dst; struct stat statbuf; fdin = open (argv[1], O_RDONLY); fdout = open (argv[2], O_RDWR | O_CREAT | O_TRUNC, FILE_MODE);
Example 2/2 fstat (fdin,&statbuf); // get size lseek (fdout, statbuf.st_size - 1, SEEK_SET); // go to the location corresponding to the last byte write (fdout, "", 1) // output file now the size of input file /* mmap the input and output file */ src = mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0); dst = mmap (0, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0); memcpy (dst, src, statbuf.st_size); } // if we wanted to write and continue we had to use munmap or msync
Signals Debt from homework
Signal(3) SYNOPSIS #include <signal.h> void (* signal(int sig, void (*func)(int)))(int); or in the equivalent but easier to read typedef'd version: typedef void (*sig_t) (int); sig_t signal(int sig, sig_t func);
Sigaction(2) (1/2) SYNOPSIS #include <signal.h> struct sigaction { union { void (*__sa_handler)(int); void (*__sa_sigaction)(int, struct __siginfo *, void *); } __sigaction_u; /* signal handler */ int sa_flags; /* see signal options below */ sigset_t sa_mask; /* signal mask to apply */ };
Sigaction(2) 2/2 #define sa_handler __sigaction_u.__sa_handler #define sa_sigaction __sigaction_u.__sa_sigaction int sigaction(int sig, const struct sigaction * restrict act, struct sigaction * restrict oact);
Kill(2) SYNOPSIS #include <signal.h> int kill(pid_t pid, int sig);
What you may do in a sig handler Signal handler are very low level code. They are invoked by the kernel, as an interrupt to the program (even while doing other system call) – some of you got EINTR on select(2) Therefore we must not get another interrupt on signal handler. Use only memory operation and non blocking system calls. (specifically avoid file I/O on signal hanglers) Getting another signal on signal handler may result in undefined behavior or even damned recursion
FAQ From homework
debugging • Gdb – lowest level • Ddd – graphical front end • Compile flag for debugging - -g • Create coredump • (tcsh) setenv coredumpsize 100000000 • (bash) ulimit –c 10000000000 • Traces: ptrace(1) strace(1) • Top : display list of process with CPU usage • Kill -9 pid = kill one of your processes
find • Grep = find in file (grep terlala *.h */*.h) • /usr/include = where most of the include are • /usr/bin = where most exe are
Vi commands for programming (1/2) • ~/.vimrc = commands that run on each new vi session • <esc>:set nu = line numbers • <esc>:set ai = auto ident • <esc>:set ts=4 = tabstop=4 • <esc>:set sw=4 = shiftwidth=4 • >> << = ident one shift width inside or outside • sy on = syntax enlightment on and off
Vi commands for programming 2/2 • Name completion, jumping to function declaration /definition = man ctags(1) • map = create shortcut for command mode • map! = create shortcut for insert mode • r = read file • r! = read the output of execuable • sh = move to shell
Interrupted system call • Check chapter 10.5 in advanced programming in the unix environment • Also do man select and check EINTR • Basicly if you get a signal such a SIGCHLD select will fail. This is condition you have to check but you don’t have to die (actually you should not die)
Syslog • In order for syslog to work you need to use LOG_LOCAL5 as facility (in openlog(3)) • Because syslog didn’t work initially we accepted file logging (but syslog is now required for homework 2) • The log file is at /var/log/messages