summaryrefslogtreecommitdiffstats
path: root/man2/dup.2
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--man2/dup.2284
1 files changed, 284 insertions, 0 deletions
diff --git a/man2/dup.2 b/man2/dup.2
new file mode 100644
index 0000000..b7187ed
--- /dev/null
+++ b/man2/dup.2
@@ -0,0 +1,284 @@
+.\" This manpage is Copyright (C) 1992 Drew Eckhardt;
+.\" and Copyright (C) 1993 Michael Haardt, Ian Jackson.
+.\" and Copyright (C) 2005, 2008 Michael Kerrisk <mtk.manpages@gmail.com>
+.\" and Copyright (C) 2014 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.\" Modified 1993-07-21, Rik Faith <faith@cs.unc.edu>
+.\" Modified 1994-08-21, Michael Chastain <mec@shell.portal.com>:
+.\" Fixed typos.
+.\" Modified 1997-01-31, Eric S. Raymond <esr@thyrsus.com>
+.\" Modified 2002-09-28, aeb
+.\" 2009-01-12, mtk, reordered text in DESCRIPTION and added some
+.\" details for dup2().
+.\" 2008-10-09, mtk: add description of dup3()
+.\"
+.TH dup 2 2023-05-03 "Linux man-pages 6.05.01"
+.SH NAME
+dup, dup2, dup3 \- duplicate a file descriptor
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.B #include <unistd.h>
+.PP
+.BI "int dup(int " oldfd );
+.BI "int dup2(int " oldfd ", int " newfd );
+.PP
+.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
+.BR "#include <fcntl.h>" " /* Definition of " O_* " constants */"
+.B #include <unistd.h>
+.PP
+.BI "int dup3(int " oldfd ", int " newfd ", int " flags );
+.fi
+.SH DESCRIPTION
+The
+.BR dup ()
+system call allocates a new file descriptor that refers to the same
+open file description as the descriptor
+.IR oldfd .
+(For an explanation of open file descriptions, see
+.BR open (2).)
+The new file descriptor number is guaranteed to be the lowest-numbered
+file descriptor that was unused in the calling process.
+.PP
+After a successful return,
+the old and new file descriptors may be used interchangeably.
+Since the two file descriptors refer to the same open file description,
+they share file offset and file status flags;
+for example, if the file offset is modified by using
+.BR lseek (2)
+on one of the file descriptors,
+the offset is also changed for the other file descriptor.
+.PP
+The two file descriptors do not share file descriptor flags
+(the close-on-exec flag).
+The close-on-exec flag
+.RB ( FD_CLOEXEC ;
+see
+.BR fcntl (2))
+for the duplicate descriptor is off.
+.\"
+.SS dup2()
+The
+.BR dup2 ()
+system call performs the same task as
+.BR dup (),
+but instead of using the lowest-numbered unused file descriptor,
+it uses the file descriptor number specified in
+.IR newfd .
+In other words,
+the file descriptor
+.I newfd
+is adjusted so that it now refers to the same open file description as
+.IR oldfd .
+.PP
+If the file descriptor
+.I newfd
+was previously open, it is closed before being reused;
+the close is performed silently
+(i.e., any errors during the close are not reported by
+.BR dup2 ()).
+.PP
+The steps of closing and reusing the file descriptor
+.I newfd
+are performed
+.IR atomically .
+This is important, because trying to implement equivalent functionality using
+.BR close (2)
+and
+.BR dup ()
+would be
+subject to race conditions, whereby
+.I newfd
+might be reused between the two steps.
+Such reuse could happen because the main program is interrupted
+by a signal handler that allocates a file descriptor,
+or because a parallel thread allocates a file descriptor.
+.PP
+Note the following points:
+.IP \[bu] 3
+If
+.I oldfd
+is not a valid file descriptor, then the call fails, and
+.I newfd
+is not closed.
+.IP \[bu]
+If
+.I oldfd
+is a valid file descriptor, and
+.I newfd
+has the same value as
+.IR oldfd ,
+then
+.BR dup2 ()
+does nothing, and returns
+.IR newfd .
+.\"
+.SS dup3()
+.BR dup3 ()
+is the same as
+.BR dup2 (),
+except that:
+.IP \[bu] 3
+The caller can force the close-on-exec flag to be set
+for the new file descriptor by specifying
+.B O_CLOEXEC
+in
+.IR flags .
+See the description of the same flag in
+.BR open (2)
+for reasons why this may be useful.
+.IP \[bu]
+.\" Ulrich Drepper, LKML, 2008-10-09:
+.\" We deliberately decided on this change. Otherwise, what is the
+.\" result of dup3(fd, fd, O_CLOEXEC)?
+If
+.I oldfd
+equals
+.IR newfd ,
+then
+.BR dup3 ()
+fails with the error
+.BR EINVAL .
+.SH RETURN VALUE
+On success, these system calls
+return the new file descriptor.
+On error, \-1 is returned, and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.TP
+.B EBADF
+.I oldfd
+isn't an open file descriptor.
+.TP
+.B EBADF
+.I newfd
+is out of the allowed range for file descriptors (see the discussion of
+.B RLIMIT_NOFILE
+in
+.BR getrlimit (2)).
+.TP
+.B EBUSY
+(Linux only) This may be returned by
+.BR dup2 ()
+or
+.BR dup3 ()
+during a race condition with
+.BR open (2)
+and
+.BR dup ().
+.TP
+.B EINTR
+The
+.BR dup2 ()
+or
+.BR dup3 ()
+call was interrupted by a signal; see
+.BR signal (7).
+.TP
+.B EINVAL
+.RB ( dup3 ())
+.I flags
+contain an invalid value.
+.TP
+.B EINVAL
+.RB ( dup3 ())
+.I oldfd
+was equal to
+.IR newfd .
+.TP
+.B EMFILE
+The per-process limit on the number of open file descriptors has been reached
+(see the discussion of
+.B RLIMIT_NOFILE
+in
+.BR getrlimit (2)).
+.SH STANDARDS
+.TP
+.BR dup ()
+.TQ
+.BR dup2 ()
+POSIX.1-2008.
+.TP
+.BR dup3 ()
+Linux.
+.SH HISTORY
+.TP
+.BR dup ()
+.TQ
+.BR dup2 ()
+POSIX.1-2001, SVr4, 4.3BSD.
+.\" SVr4 documents additional
+.\" EINTR and ENOLINK error conditions. POSIX.1 adds EINTR.
+.\" The EBUSY return is Linux-specific.
+.TP
+.BR dup3 ()
+Linux 2.6.27,
+glibc 2.9.
+.SH NOTES
+The error returned by
+.BR dup2 ()
+is different from that returned by
+.BR fcntl( "..., " F_DUPFD ", ..." )
+when
+.I newfd
+is out of range.
+On some systems,
+.BR dup2 ()
+also sometimes returns
+.B EINVAL
+like
+.BR F_DUPFD .
+.PP
+If
+.I newfd
+was open, any errors that would have been reported at
+.BR close (2)
+time are lost.
+If this is of concern,
+then\[em]unless the program is single-threaded and does not allocate
+file descriptors in signal handlers\[em]the correct approach is
+.I not
+to close
+.I newfd
+before calling
+.BR dup2 (),
+because of the race condition described above.
+Instead, code something like the following could be used:
+.PP
+.in +4n
+.EX
+/* Obtain a duplicate of \[aq]newfd\[aq] that can subsequently
+ be used to check for close() errors; an EBADF error
+ means that \[aq]newfd\[aq] was not open. */
+\&
+tmpfd = dup(newfd);
+if (tmpfd == \-1 && errno != EBADF) {
+ /* Handle unexpected dup() error. */
+}
+\&
+/* Atomically duplicate \[aq]oldfd\[aq] on \[aq]newfd\[aq]. */
+\&
+if (dup2(oldfd, newfd) == \-1) {
+ /* Handle dup2() error. */
+}
+\&
+/* Now check for close() errors on the file originally
+ referred to by \[aq]newfd\[aq]. */
+\&
+if (tmpfd != \-1) {
+ if (close(tmpfd) == \-1) {
+ /* Handle errors from close. */
+ }
+}
+.EE
+.in
+.SH SEE ALSO
+.BR close (2),
+.BR fcntl (2),
+.BR open (2),
+.BR pidfd_getfd (2)