File I/O open close lseek read and write – unbuffered I/O dup and dup2 File Descriptors Kernel maintains file descriptors to reference open files Non-negative integer The shell defines 3 by convention stdin 0 stdout 1 stderr 2 Open Functions defined in <unistd.h> open function int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); Open (cont) Required Flags O_RDONLY O_WRONLY O_RDWR Useful Optional Flags O_APPEND O_CREAT O_EXCL (used with O_CREAT to cause the open function to fail if file already exists) O_TRUNC Open Example int fd; fd = open(“data.txt”, O_RDONLY | O_CREAT | O_TRUNC, mode); if(fd < 0) { perror(“Unable to open file”); exit(1); } creat creat function int creat(const char *pathname, mode_t mode); Same as using open with O_WRONLY | O_CREAT | O_TRUNC, mode) close close function int close(int fd); Returns 0 on success or -1 on error Kernel will close any file descriptors left open by a process when it exits lseek lseek function off_t lseek(int fildes, off_t offset, int whence); Returns current file offset if sucessful, otherwise -1 whence SEEK_SET – Sets offset from beginning of file SEEK_CUR – Relative offset from current position SEEK_END – Sets offset past end of file Unbuffered I/O - read read function ssize_t read(int fd, void *buf, size_t count); Reads count bytes from the file indicated by the file descriptor fd into the buffer pointed to by buf Returns -1 on error, 0 on end of file and number of bytes read otherwise (may be less that the number requested) Unbuffered I/O - write write function ssize_t write(int fd, const void *buf, size_t count); Attempts to write out count bytes from buffer buf to file indicated by file descriptor fd. Returns -1 on error, number of bytes written otherwise Buffer Size and Efficiency Program in Fig 3.4 page 69 Table in Fig 3.5 page 70 File Sharing Multiple processes can access a file simultaneously 3 Kernel level data structures are used to keep track of file information Process table File table v-node See Fig 3.6 and 3.7 on pages 72, 73 Atomic Operations Appending to a file Separate lseek and write operations can result in race conditions Open file with O_APPEND to force an atomic seek to end of file before each write Creating a file Separate check for file existence and creation can result in race condition Use both the O_CREAT and O_EXCL flags dup and dup2 Both are functions for duplicating a file descriptor within a process and return -1 on error dup int dup(int oldfd); Returns a new fd that points to the same entry in the file table dup2 int dup2(int oldfd, int newfd); Returns newfd which now points to the same entry in the file table as oldfd fcntl Allows us to change properties of an already opened file Several uses. See page 78 for more info All return -1 on error, but meaning of other return types depends on specific use ioctl int ioctl(int d, int request, ...); Catchall for I/O functions that don’t fit well in other headers.