This chapter has described the traditional Unix I/O functions. These are often called the unbuffered I/O functions because each read or write invokes a system call into the kernel. Using only read and write we looked at the effect of different I/O sizes on the amount of time required to read a file.
Atomic operations were introduced when multiple processes append to the same file and when multiple processes create the same file. We also looked at the data structures used by the kernel to share information about open files. We'll return to these data structures later in the text.
We also described the ioctl and fcntl functions. We return to both of these functions in Chapter 12—we'll use ioctl with the streams I/O system, and fcntl is used for record locking.
When reading or writing a disk file, are the functions described in this chapter really unbuffered? Explain.
Write your own function called dup2 that performs the same service as the dup2 function we described in Section 3.12, without calling the fcntl function. Be sure to handle errors correctly.
Assume a process executes the following three function calls:
fd1 = open(pathname, oflags); fd2 = dup(fd1); fd3 = open(pathname, oflags);
Draw the resulting picture, similar to Figure 3.4. Which descriptors are affected by an fcntl on fd1 with a command of F_SETFD? Which descriptors are affected by an fcntl on fd1 with a command of F_SETFL?
The following sequence of code has been observed in various programs:
dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); if (fd > 2) close(fd);
To see why the if test is needed, assume fd is 1 and draw a picture of what happens to the three descriptor entries and the corresponding file table entry with each call to dup2. Then assume fd is 3 and draw the same picture.
The Bourne shell and KornShell notation
says to redirect descriptor digit1 to the same file as descriptor digit2. What is the difference between the two commands
a.out > outfile 2>&1 a.out 2>&1 > outfile
(Hint: the shells process their command lines from left to right.)
If you open a file for read-write with the append flag, can you still read from anywhere in the file using lseek? Can you use lseek to replace existing data in the file? Write a program to verify this.