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>
 .\" 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.
 .\" 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.
 .\"
 .\" 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>:
 .\"
 .\" 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()
 .\"
 .\"     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
 .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
 .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
 .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 ()
 .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 ()
 .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
 .IP * 3
 If
 .I oldfd
@@ -75,24 +120,8 @@ then
 .BR dup2 ()
 does nothing, and returns
 .IR newfd .
 .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 (),
 .BR dup3 ()
 is the same as
 .BR dup2 (),
@@ -116,7 +145,7 @@ then
 .BR dup3 ()
 fails with the error
 .BR EINVAL .
 .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
 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
 .TP
 .B EBADF
 .I oldfd
-isn't an open file descriptor, or
+isn't an open file descriptor.
+.TP
+.B EBADF
 .I newfd
 .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
 .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.
 .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
 .\" 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
 .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 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.
 .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.
 when
 .I newfd
 is out of range.
-On some systems
+On some systems,
 .BR dup2 ()
 also sometimes returns
 .B EINVAL
 .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.
 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
 .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)
 .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/.