Unit 5: Low-Level I/O CptS 360 (System Programming) Unit 5: Low-Level I/O Bob Lewis School of Engineering and Applied Sciences Washington State University Spring, 2020 Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O Motivation ◮ All file and device (and some network) input/output ultimately uses these routines. ◮ Most of them map one-to-one to kernel system calls. ◮ This is the functionality all I/O drivers have to provide. Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O References ◮ Stevens & Rago Ch. 3 Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O Introduction ◮ Recall system/utility library interface diagram. ◮ These all work with file descriptors . ◮ Q: What is the C type used for a file descriptor? ◮ Q: What are the typical values of file descriptors? ◮ All programs start with 3 open file descriptors. ◮ Q: What are they and what do they correspond to? Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O open(2) and creat(2) Opens or creates a file for reading or writing. prototypes: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode); creat() is equivalent to open() with flags set to O_CREAT|O_WRONLY|O_TRUNC Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O common open(2) flags ◮ O_RDONLY , O_WRONLY , or O_RDWR read-only, write-only, read/write (choose one) ◮ O_APPEND append ◮ O_CREAT create file if it doesn’t exist ◮ O_EXCL exclusive access (with O_CREAT , make sure file is created by caller) ◮ O_TRUNC truncate to length 0 Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O less-used open(2) flags ◮ O_NOCTTY if opening a device, don’t make it the control tty ◮ O_NONBLOCK or O_NDELAY nonblocking open/access – caller will never wait ◮ O_SYNC sync for each physical I/O (generally not a good idea – why?) Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O The mode argument ◮ Remember “ ugo ” for mode flags. ◮ Primitive (early UNIX) security notion divides the world into three classes: ◮ user ◮ members of the user’s group ◮ ”other” ◮ mode is only used when O_CREAT is one of the flags . Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O mode is a mask (in octal) also set in 00400 user read S_IRUSR S_IRWXU 00200 user write S_IWUSR S_IRWXU 00100 user execute S_IXUSR S_IRWXU 00040 group read S_IRGRP S_IRWXG 00020 group write S_IWGRP S_IRWXG 00010 group execute S_IXGRP S_IRWXG 00004 others read S_IROTH S_IRWXO 00002 others write S_IWOTH S_IRWXO 00001 others execute S_IXOTH S_IRWXO Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O umask(2) Sets the calling process’s “file creation mask”. prototype: #include <sys/types.h> #include <sys/stat.h> mode_t umask(mode_t mask); ◮ Set before open() / creat() . ◮ “umask” is a process attribute, but it affects open() and creat() . ◮ The umask bitmask says: “Turn these mode bits off, even if the application says to turn them on.” ◮ File creation mask = (mode & ~umask) where mode is the argument to open() or creat() . Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O close(2) protoype: #include <unistd.h> int close(int fd); ◮ pretty straightforward ◮ Q: Why not close fd’s 0, 1, and 2? Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O lseek(2) Randomly positions a file for reading or writing. prototype: #include <sys/types.h> #include <unistd.h> off_t lseek(int fildes, off_t offset, int whence); ◮ Q: Can you lseek() ◮ standard input ( filedes == 0)? ◮ standard output ( filedes == 1)? ◮ whence should be one of: ◮ SEEK_SET ◮ SEEK_CUR ◮ SEEK_END ◮ Take a look at lseek64(3) . Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O read(2) and write(2) These are the primary low-level I/O functions. read() prototype: #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); Note: returned value may not equal count. write() prototype: #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O I/O Efficiency Q: What’s are the advantages of these routines over those in the Standard I/O library (TBD)? Vice Versa? ◮ No buffering (with some exceptions). ◮ Direct control to user. ◮ Performance could go either way. Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O File Sharing ◮ Two processes on the same system can share the same file. ◮ OK for one writer, N readers. ◮ Not so for > 1 writer. Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O Simultaneous Operations ◮ Consider two processes doing an lseek() to EOF, followed by write() . ◮ Workaround: O_APPEND ◮ Simultaneous file creation if file doesn’t already exist... ◮ resolved with O_CREAT and O_EXCL flags to open() . Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O dup(2) and dup2(2) Duplicates one file descriptor to another. prototype: #include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd); ◮ dup2(foo, bar); closes ”bar” before dupping it ◮ Handy: Lets you direct two already-open files (e.g. standard output and standard error) to the same place. ◮ This is how $ myprog 2>&1 | less works. Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O fcntl(2) Miscellaneous “file control” functions. prototype: #include <unistd.h> #include <fcntl.h> int fcntl(fd, cmd[, arg]); Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O fcntl(2) Commands cmd can be: ◮ F_DUPFD duplicates fd as the lowest file descriptor (“ dup(foo) ” is equivalent to “ fcntl(foo, F_DUPFD, 0) ”) ◮ F_SETFD sets the close-on-exec (which is?) flag to arg ◮ F_GETFD returns the close-on-exec flag ◮ F_SETFL sets descriptors ( O_APPEND , O_NONBLOCK , O_ASYNC only) ...and other stuff having to do with signalling I/O and other kinds of (open) file related flags. Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O ioctl(2) Device-related controls (more so than fctnl(2) ). prototype: #include <sys/ioctl.h> int ioctl(int df, int cmd[, ... ]); ◮ disk labels ◮ device control (e.g., CD/DVD eject) ◮ mag tape control (e.g., BPI) ◮ socket I/O ◮ terminal I/O esp. character-at-a-time I/O (e.g. stty) This is a catch-all function for the device driver. Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O /dev/fd/* ◮ On Linux (mainly). ◮ Allows standardized access to standard input, standard output, and standard error, even though the executable might not permit it. ◮ Occasionally useful. ◮ Q: Why does $ ls /dev/fd list four file descriptors, and $ ls /dev/fd/0 works, but $ ls /dev/fd/3 fails. (You have to think through what’s going on.) Bob Lewis WSU CptS 360 (Spring, 2020)
Unit 5: Low-Level I/O Summary Two related questions: ◮ Why are there so few device-related system calls per device? ◮ What does it mean to implement a device driver? Bob Lewis WSU CptS 360 (Spring, 2020)
Recommend
More recommend