DUP(2)

DUP(2) | System Calls Manual | DUP(2)

# NAME

`dup`, `dup2`, `dup3` — duplicate an existing file descriptor

# LIBRARY

Standard C Library (libc, -lc)

# SYNOPSIS

`#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);

# DESCRIPTION

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_CLOEXEC`
  Set the close-on-exec flag on newfd.
`O_CLOFORK`
  Set the close-on-fork flag on newfd.
`O_NONBLOCK`
  Sets non-blocking I/O.
`O_NOSIGPIPE`
  For pipes and sockets, do not raise `SIGPIPE` 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).

# RETURN VALUES

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.

# EXAMPLES

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];

# ERRORS

These functions fail if:

[`EBADF`]
  oldfd is not a valid active descriptor, or for `dup2`() and `dup3`(), newfd is not in the range of valid file descriptors.
[`EINVAL`]
  In the `dup3`() call either the flags argument contained an invalid value or the oldfd argument is equal to the newfd argument.
[`EMFILE`]
  Too many descriptors are active. Only `dup`() can generate this error.

# SEE ALSO

accept(2), close(2), fcntl(2), getrlimit(2), open(2), pipe(2), setrlimit(2), socket(2), socketpair(2), getdtablesize(3)

# STANDARDS

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”).

# HISTORY

The `dup3`() function originated in Linux and appeared in NetBSD 6.0.

July 8, 2025 | NetBSD 11.0