|
Advanced Programming in the UNIX Environment Authors: Stevens R., Rago S.A. Published year: 2005 Pages: 58-59/370 |
|
|
3.12. dup and dup2 FunctionsAn existing file descriptor is duplicated by either of the following functions.
The new file descriptor returned by dup is guaranteed to be the lowest -numbered available file descriptor. With dup2 , we specify the value of the new descriptor with the filedes2 argument. If filedes2 is already open , it is first closed. If filedes equals filedes2 , then dup2 returns filedes2 without closing it. The new file descriptor that is returned as the value of the functions shares the same file table entry as the filedes argument. We show this in Figure 3.8. Figure 3.8. Kernel data structures after dup (1)
In this figure, we're assuming that when it's started, the process executes newfd = dup(1); We assume that the next available descriptor is 3 (which it probably is, since 0, 1, and 2 are opened by the shell). Because both descriptors point to the same file table entry, they share the same file status flagsread, write, append, and so onand the same current file offset. Each descriptor has its own set of file descriptor flags. As we describe in the next section, the close-on- exec file descriptor flag for the new descriptor is always cleared by the dup functions. Another way to duplicate a descriptor is with the fcntl function, which we describe in Section 3.14. Indeed, the call dup(filedes); is equivalent to fcntl(filedes, F_DUPFD, 0); Similarly, the call dup2(filedes, filedes2); is equivalent to
close(filedes2);
fcntl(filedes, F_DUPFD, filedes2);
In this last case, the dup2 is not exactly the same as a close followed by an fcntl . The differences are as follows .
|
|
|
|
|
3.13. sync , fsync , and fdatasync FunctionsTraditional implementations of the UNIX System have a buffer cache or page cache in the kernel through which most disk I/O passes . When we write data to a file, the data is normally copied by the kernel into one of its buffers and queued for writing to disk at some later time. This is called delayed write . (Chapter 3 of Bach [1986] discusses this buffer cache in detail.) The kernel eventually writes all the delayed-write blocks to disk, normally when it needs to reuse the buffer for some other disk block. To ensure consistency of the file system on disk with the contents of the buffer cache, the sync , fsync , and fdatasync functions are provided.
The sync function simply queues all the modified block buffers for writing and returns; it does not wait for the disk writes to take place. The function sync is normally called periodically (usually every 30 seconds) from a system daemon, often called update . This guarantees regular flushing of the kernel's block buffers. The command sync (1) also calls the sync function. The function fsync refers only to a single file, specified by the file descriptor filedes , and waits for the disk writes to complete before returning. The intended use of fsync is for an application, such as a database, that needs to be sure that the modified blocks have been written to the disk. The fdatasync function is similar to fsync , but it affects only the data portions of a file. With fsync , the file's attributes are also updated synchronously.
|
|
|
|
Advanced Programming in the UNIX Environment Authors: Stevens R., Rago S.A. Published year: 2005 Pages: 58-59/370 |