OSDN Git Service

LDP: Update original to LDP v3.79
[linuxjm/LDP_man-pages.git] / original / man2 / dup.2
index c4ac032..e344b72 100644 (file)
@@ -1,9 +1,9 @@
-.\" Hey Emacs! This file is -*- nroff -*- source.
-.\"
 .\" 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>
 .\"
+.\" %%%LICENSE_START(VERBATIM)
 .\" Permission is granted to make and distribute verbatim copies of this
 .\" manual provided the copyright notice and this permission notice are
 .\" preserved on all copies.
@@ -23,6 +23,7 @@
 .\"
 .\" Formatted or processed versions of this manual, if unaccompanied by
 .\" the source, must acknowledge the copyright and authors of this work.
+.\" %%%LICENSE_END
 .\"
 .\" Modified 1993-07-21, Rik Faith <faith@cs.unc.edu>
 .\" Modified 1994-08-21, Michael Chastain <mec@shell.portal.com>:
@@ -33,7 +34,7 @@
 .\"     details for dup2().
 .\" 2008-10-09, mtk: add description of dup3()
 .\"
-.TH DUP 2 2008-10-09 "Linux" "Linux Programmer's Manual"
+.TH DUP 2 2015-01-22 "Linux" "Linux Programmer's Manual"
 .SH NAME
 dup, dup2, dup3 \- duplicate a file descriptor
 .SH SYNOPSIS
@@ -43,21 +44,65 @@ dup, dup2, dup3 \- duplicate a file descriptor
 .BI "int dup(int " oldfd );
 .BI "int dup2(int " oldfd ", int " newfd );
 .sp
-.B #define _GNU_SOURCE
+.BR "#define _GNU_SOURCE" "             /* See feature_test_macros(7) */"
+.BR "#include <fcntl.h>" "              /* Obtain O_* constant definitions */
 .B #include <unistd.h>
 .sp
 .BI "int dup3(int " oldfd ", int " newfd ", int " flags );
 .fi
 .SH DESCRIPTION
-These system calls create a copy of the file descriptor
-.IR oldfd .
-
+The
 .BR dup ()
-uses the lowest-numbered unused descriptor for the new descriptor.
+system call creates a copy of the file descriptor
+.IR oldfd ,
+using the lowest-numbered unused descriptor for the new descriptor.
 
+After a successful return,
+the old and new file descriptors may be used interchangeably.
+They refer to the same open file description (see
+.BR open (2))
+and thus share file offset and file status flags;
+for example, if the file offset is modified by using
+.BR lseek (2)
+on one of the descriptors, the offset is also changed for the other.
+
+The two 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 ()
-.RI "makes " newfd " be the copy of " oldfd ", closing " newfd
-first if necessary, but note the following:
+system call performs the same task as
+.BR dup (),
+but instead of using the lowest-numbered unused file descriptor,
+it uses the descriptor number specified in
+.IR newfd .
+If the descriptor
+.IR newfd
+was previously open, it is silently closed before being reused.
+
+The steps of closing and reusing the file descriptor
+.IR 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.
+
+Note the following points:
 .IP * 3
 If
 .I oldfd
@@ -75,24 +120,8 @@ then
 .BR dup2 ()
 does nothing, and returns
 .IR newfd .
-.PP
-After a successful return from one of these system calls,
-the old and new file descriptors may be used interchangeably.
-They refer to the same open file description (see
-.BR open (2))
-and thus share file offset and file status flags;
-for example, if the file offset is modified by using
-.BR lseek (2)
-on one of the descriptors, the offset is also changed for the other.
-
-The two 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 dup3()
 .BR dup3 ()
 is the same as
 .BR dup2 (),
@@ -116,7 +145,7 @@ then
 .BR dup3 ()
 fails with the error
 .BR EINVAL .
-.SH "RETURN VALUE"
+.SH RETURN VALUE
 On success, these system calls
 return the new descriptor.
 On error, \-1 is returned, and
@@ -126,9 +155,14 @@ is set appropriately.
 .TP
 .B EBADF
 .I oldfd
-isn't an open file descriptor, or
+isn't an open file descriptor.
+.TP
+.B EBADF
 .I newfd
-is out of the allowed range for file descriptors.
+is out of the allowed range for file descriptors (see the discussion of
+.BR RLIMIT_NOFILE
+in
+.BR getrlimit (2)).
 .TP
 .B EBUSY
 (Linux only) This may be returned by
@@ -152,21 +186,26 @@ call was interrupted by a signal; see
 .RB ( dup3 ())
 .I flags
 contain an invalid value.
+.TP
+.B EINVAL
+.RB ( dup3 ())
 .\" FIXME . To confirm with Al Viro that this was intended, and its rationale
-Or,
 .I oldfd
 was equal to
 .IR newfd .
 .TP
 .B EMFILE
 The process already has the maximum number of file
-descriptors open and tried to open a new one.
+descriptors open and tried to open a new one (see the discussion of
+.BR RLIMIT_NOFILE
+in
+.BR getrlimit (2)).
 .SH VERSIONS
 .BR dup3 ()
 was added to Linux in version 2.6.27;
 glibc support is available starting with
 version 2.9.
-.SH "CONFORMING TO"
+.SH CONFORMING TO
 .BR dup (),
 .BR dup2 ():
 SVr4, 4.3BSD, POSIX.1-2001.
@@ -184,7 +223,7 @@ is different from that returned by
 when
 .I newfd
 is out of range.
-On some systems
+On some systems,
 .BR dup2 ()
 also sometimes returns
 .B EINVAL
@@ -196,14 +235,52 @@ If
 was open, any errors that would have been reported at
 .BR close (2)
 time are lost.
-A careful programmer will not use
-.BR dup2 ()
-or
-.BR dup3 ()
-without closing
+If this is of concern,
+then\(emunless the program is single-threaded and does not allocate
+file descriptors in signal handlers\(emthe correct approach is
+.I not
+to close
 .I newfd
-first.
-.SH "SEE ALSO"
+before calling
+.BR dup2 (),
+because of the race condition described above.
+Instead, code something like the following could be used:
+
+.nf
+    /* Obtain a duplicate of 'newfd' that can subsequently
+       be used to check for close() errors; an EBADF error
+       means that 'newfd' was not open. */
+
+    tmpfd = dup(newfd);
+    if (tmpfd == \-1 && errno != EBADF) {
+        /* Handle unexpected dup() error */
+    }
+
+    /* Atomically duplicate 'oldfd' on 'newfd' */
+
+    if (dup2(oldfd, newfd) == \-1) {
+        /* Handle dup2() error */
+    }
+
+    /* Now check for close() errors on the file originally
+       referred to by 'newfd' */
+
+    if (tmpfd != \-1) {
+        if (close(tmpfd) == \-1) {
+            /* Handle errors from close */
+        }
+    }
+.fi
+.SH SEE ALSO
 .BR close (2),
 .BR fcntl (2),
 .BR open (2)
+.SH COLOPHON
+This page is part of release 3.79 of the Linux
+.I man-pages
+project.
+A description of the project,
+information about reporting bugs,
+and the latest version of this page,
+can be found at
+\%http://www.kernel.org/doc/man\-pages/.