Both of the following functions can be used to copy an existing file descriptor.
#include <unistd.h>
int dup(int fd);
int dup2(int fd,int fd2);
The return values of the two functions: if successful, return a new file descriptor: if an error occurs, return -1
The new file descriptor returned dup()
must be the smallest number of currently available file descriptors. For , the value of the new descriptor dup2()
can be specified with parameters. fd2
If fd2
it is already open, close it first. If fd
equal fd2
, dup2()
return fd2
without closing it. Otherwise, fd2
the FD_CLOEXEC
file descriptor flag is cleared so that fd2
it is open when the process calls exec.
The new file descriptor returned by these functions shares the same file table entry as the parameter fd
In this diagram, we assume that the process starts by executing:
newfd dup(1);
When this function starts executing, it is assumed that the next available descriptor is 3 (which is very possible since 0, 1 and 2 are all opened by the shell). Because both descriptors point to the same file table entry, they share the same file status flags (read, write, append, etc.) and the same current file offset.
Each file descriptor has its own set of file descriptor flags. The close-on-exec flag of a new descriptor is always dup
cleared by the function.
Another way to copy a descriptor is to use fcntl
a function. In fact, calling
dup(fd);
Equivalent to
fcntl(fd, F_DUPFD, 0);
And call
dup2(fd, fd2);
Equivalent to
close(fd2);
fcntl(fd, F_DUPFD, fd2);
In the latter case, dup2 is not exactly equivalent to close
plus fcntl
. The differences between them are as follows:
dup2
is an atomic operation, andclose
betweenfcntl
the two function calls, it is possible that the signal catching function is called betweenclose
and , which may modify the file descriptor.fcntl
The same problem will occur if a different thread changes the file descriptordup2
andfcnt1
there are some different errno's.
"UNIX Environment Programming"