diff options
Diffstat (limited to 'man2/dup.2')
-rw-r--r-- | man2/dup.2 | 284 |
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) |