FilesQuizFile APIreadread() boundary cases to trip you upIt usually works as you might assumeread() boundary cases Practical GuideSequential bytes != C stringGet and maintain a reference to a fileopen – read – closeopen –... – read – ... – closeWhat can go wrong with open?Slide 13statstat versionsSlide 16Stat macros (st_mode)open –... – stat – ... – closeDirectoriesDirectoriesFile DescriptorsUNIX file structure implementationAllocation of Disk SpaceContiguous AllocationContiguous Allocation IssuesSlide 26External Fragmentation Solution: Linked allocationLinked AllocationLinked List AllocationSlide 30Linked List Allocation IssuesSlide 32#3. Indexed AllocationIndexed AllocationSlide 35Linked Indexed FilesMultilevel Indexed FileCopyright ©: Nahrstedt, Angrave, Abdelzaher 1FilesCopyright ©: Nahrstedt, Angrave, Abdelzaher2QuizA server has an average service time of 0.1 seconds per request. Requests arrive at a rate of 7 requests per second. What is the server utilization?Copyright ©: Nahrstedt, Angrave, Abdelzaher3File API#include <unistd.h>ssize_t read(int dec, void *buf, size_t nbyte);Copyright ©: Nahrstedt, Angrave, Abdelzaher4readDon't need to read entire file... Grab bytes into your buffer... Next call to read will read next unread byteCan even read the bytes of a 'directory'Copyright ©: Nahrstedt, Angrave, Abdelzaher5read() boundary cases to trip you upMay not read anything signal interruptionend of fileasynchronous non-blocking modehardware issueNeed to check # bytes actually readCopyright ©: Nahrstedt, Angrave, Abdelzaher6It usually works as you might assumeUpon successful completion, read(), returns the number of bytes actually read and placed in the buffer. The system guarantees to read the number of bytes requested if the descriptor references a normal file that has that many bytes left before the end-of-file, but in no other case.Copyright ©: Nahrstedt, Angrave, Abdelzaher7read() boundary cases Practical GuideReturn 0: End of FileReturn -1: Check errno and act accordinglye.g. EINTR; restartReturn +N: # bytes placed into bufferCopyright ©: Nahrstedt, Angrave, Abdelzaher8Sequential bytes != C string Doesn't know or care about strings and NUL bytesEnsure NUL termination before using printf debug statements contents!Copyright ©: Nahrstedt, Angrave, Abdelzaher9Get and maintain a reference to a filePOSIX open()Let's dig deeper...... Errors and options... Directory organization & implementation... How does O/S Manage file descriptors?Copyright ©: Nahrstedt, Angrave, Abdelzaher10open – read – closefd=open("/tmp/1.txt", options);read(fd,buffer,sizeof(buffer));close(fd);Copyright ©: Nahrstedt, Angrave, Abdelzaher11open –... – read – ... – closefd=open("/tmp/1.txt", options);if(fd <1) error (e.g. File doesn't exist)r=read(fd,buffer,sizeof(buffer))handle special cases (eof,restart, media errors)close(fd);free up resourcesCopyright ©: Nahrstedt, Angrave, Abdelzaher12What can go wrong with open?Copyright ©: Nahrstedt, Angrave, Abdelzaher13EACCES The requested access to the file is not allowed, or search permission is denied for one of the directories in the path prefix of pathname, or the file did not exist yet and write access to the parent directory is not allowed. (See also path_resolution(2).) EEXIST pathname already exists and O_CREAT and O_EXCL were used. EFAULT pathname points outside your accessible address space. EISDIR pathname refers to a directory and the access requested involved writing (that is, O_WRONLY or O_RDWR is set). ELOOP Too many symbolic links were encountered in resolving pathname, or O_NOFOLLOW was specified but pathname was a symbolic link. EMFILE The process already has the maximum number of files open. ENAMETOOLONG pathname was too long. ENFILE The system limit on the total number of open files has been reached. ENODEV pathname refers to a device special file and no corresponding device exists. (This is a Linux kernel bug; in this situation ENXIO must be returned.) ENOENT O_CREAT is not set and the named file does not exist. Or, a directory component in pathname does not exist or is a dangling symbolic link. ENOMEM Insufficient kernel memory was available. ENOSPC pathname was to be created but the device containing pathname has no room for the new file. ENOTDIR A component used as a directory in pathname is not, in fact, a directory, or O_DIRECTORY was specified and pathname was not a directory. ENXIO O_NONBLOCK | O_WRONLY is set, the named file is a FIFO and no process has the file open for reading. Or, the file is a device special file and no corresponding device exists. EOVERFLOW pathname refers to a regular file, too large to be opened; see O_LARGEFILE above. EPERM The O_NOATIME flag was specified, but the effective user ID of the caller did not match the owner of the file and the caller was not privileged (CAP_FOWNER). EROFS pathname refers to a file on a read-only filesystem and write access was requested. ETXTBSY pathname refers to an executable image which is currently being executed and write access was requested. EWOULDBLOCK The O_NONBLOCK flag was specified, and an incompatible lease was held on the file (see fcntl(2)).What can go wrong with open?Copyright ©: Nahrstedt, Angrave, Abdelzaher14statMeta-information about a filemodification and access timeKind of file (e.g. Directory | regular file?)Support for symbolic linksCopyright ©: Nahrstedt, Angrave, Abdelzaher15stat versionsThree flavorsint stat(const char *path, struct stat *buf); int fstat(int fileID, struct stat *buf); Info about link (more on this later)int lstat(const char *path, struct stat *buf);Copyright ©: Nahrstedt, Angrave, Abdelzaher16struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* mode and protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for filesystem I/O */ blkcnt_t st_blocks; /* number of blocks allocated */ time_t st_atime;
View Full Document