| DUP(2) | System Calls Manual | DUP(2) |
dup, dup2,
dup3 — duplicate an existing
file descriptor
Standard C Library (libc, -lc)
#include
<unistd.h>
int
dup(int
oldfd);
int
dup2(int
oldfd, int
newfd);
#include <fcntl.h>
#include <unistd.h>
int
dup3(int
oldfd, int newfd,
int flags);
The
dup()
family of calls duplicates an existing file descriptor
oldfd. A new file descriptor is produced; it is a new
reference to the same underlying system object. The object in question does
not distinguish between the descriptors referencing it in any way. Thus for
files, read(2),
write(2) and
lseek(2) calls all move a
single shared seek position. Similarly, all object modes, settings,
properties, and behavior other than the close-on-exec & close-on-fork
flags are shared between references. This includes the setting of append
mode, non-blocking I/O actions, asynchronous I/O operations in progress,
socket options, and so forth. The close-on-exec & close-on-fork flags,
however, are a property of the descriptor rather than the object and can be
set independently for each reference.
To get an independent handle with its own seek position and settings, an additional open(2) call must be issued. (This is not generally possible for pipes and sockets.)
The
dup() call
chooses the new descriptor: it is the lowest-numbered descriptor not
currently in use. The
dup2()
and dup3() calls allow the caller to choose the new
descriptor by passing newfd, which must be within the
range of valid descriptors. If newfd is the same as
oldfd, in dup2() the call has
no effect, whereas it is an error in dup3().
Otherwise, if newfd is already in use, it is closed as
if close(2) had been
called.
File descriptors are small non-negative integers that index into
the per-process file table. Values 0, 1, and 2 have the special property
that they are treated as standard input, standard output, and standard error
respectively. (The constants STDIN_FILENO,
STDOUT_FILENO, and
STDERR_FILENO are provided as symbolic forms for
these values.) The maximum value for a file descriptor is one less than the
file table size. The file table size can be interrogated with
getdtablesize(3) and
can to some extent be adjusted with
setrlimit(2).
The
dup3() call
fails and returns EINVAL if the numeric value in the
oldfd argument is equal to the one in the
newfd argument. It also includes an additional
flags argument supporting a subset of the
open(2) flags:
O_CLOEXECO_CLOFORKO_NONBLOCKO_NOSIGPIPESIGPIPE when a
write is made to a broken pipe. Instead, the write will fail with
EPIPE.As described above, only the close-on-exec and
close-on-fork flags are per-file-descriptor, so passing any of the other
flags will affect both oldfd and
newfd. These settings are, however, applied atomically
along with the rest of the
dup3()
operation.
In the case of
dup() and
dup2()
the close-on-exec and close-on-fork flags on the new file descriptor are
always left unset and all the modes and settings of the underlying object
are left unchanged.
Functionality similar to
dup() with
slightly different semantics is also available via
fcntl(2).
When successful, these calls return the new file descriptor value.
In the case of dup2() and
dup3() this is always the same as
newfd. If an error occurs, the value -1 is returned
and errno is set to indicate what happened.
A common use for these functions is to set up a pipe as the standard input or standard output of a subprocess. That is done approximately as follows (with error handling omitted for clarity):
#include <unistd.h>
int fds[2];
pid_t pid;
pipe(fds);
pid = fork();
if (pid == 0) {
/* child; use read end of pipe to stdin */
dup2(fds[0], STDIN_FILENO);
close(fds[0]);
close(fds[1]);
execv("/some/program", args);
}
/* parent process; return write end of pipe */
close(fds[0]);
return fds[1];
These functions fail if:
EBADF]dup2() and dup3(),
newfd is not in the range of valid file
descriptors.EINVAL]dup3() call either the
flags argument contained an invalid value or the
oldfd argument is equal to the
newfd argument.EMFILE]dup() can
generate this error.accept(2), close(2), fcntl(2), getrlimit(2), open(2), pipe(2), setrlimit(2), socket(2), socketpair(2), getdtablesize(3)
The dup() and
dup2() functions conform to IEEE
Std 1003.1-1990 (“POSIX.1”). The
dup3() function conforms to IEEE
Std 1003.1-2024 (“POSIX.1”).
The dup3() function originated in Linux
and appeared in NetBSD 6.0.
| July 8, 2025 | NetBSD 11.0 |