Module Name: src Committed By: dholland Date: Tue Dec 24 22:31:11 UTC 2013
Modified Files: src/lib/libc/sys: dup.2 Log Message: Rewrite for clarity and add an example. To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/lib/libc/sys/dup.2 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/sys/dup.2 diff -u src/lib/libc/sys/dup.2:1.28 src/lib/libc/sys/dup.2:1.29 --- src/lib/libc/sys/dup.2:1.28 Wed Jan 25 00:28:35 2012 +++ src/lib/libc/sys/dup.2 Tue Dec 24 22:31:11 2013 @@ -1,4 +1,4 @@ -.\" $NetBSD: dup.2,v 1.28 2012/01/25 00:28:35 christos Exp $ +.\" $NetBSD: dup.2,v 1.29 2013/12/24 22:31:11 dholland Exp $ .\" .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" @(#)dup.2 8.1 (Berkeley) 6/4/93 .\" -.Dd January 23, 2012 +.Dd December 24, 2013 .Dt DUP 2 .Os .Sh NAME @@ -42,129 +42,190 @@ .Sh SYNOPSIS .In unistd.h .Ft int -.Fn dup "int oldd" +.Fn dup "int oldfd" .Ft int -.Fn dup2 "int oldd" "int newd" +.Fn dup2 "int oldfd" "int newfd" .Ft int -.Fn dup3 "int oldd" "int newd" "int flags" +.Fn dup3 "int oldfd" "int newfd" "int flags" .Sh DESCRIPTION +The .Fn dup -duplicates an existing object descriptor and returns its value to -the calling process -.Fa ( newd -= -.Fn dup oldd ) . -The argument -.Fa oldd -is a small non-negative integer index in -the per-process descriptor table. -The value must be less than the size of the table, which is returned by -.Xr getdtablesize 3 . -The new descriptor returned by the call -is the lowest numbered descriptor currently not in use by the process. -.Pp -The object referenced by the descriptor does not distinguish -between -.Fa oldd -and -.Fa newd -in any way. -Thus if -.Fa newd -and -.Fa oldd -are duplicate references to an open -file, +family of calls duplicates an existing file descriptor +.Fa 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, .Xr read 2 , .Xr write 2 and .Xr lseek 2 -calls all move a single pointer into the file, -and append mode, non-blocking I/O and asynchronous I/O options -are shared between the references. -If a separate pointer into the file is desired, a different -object reference to the file must be obtained by issuing an -additional +calls all move a single shared seek position. +Similarly, all object modes, settings, properties, and behavior other +than the close-on-exec flag 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 flag, however, is a property of the descriptor +rather than the object and can be set independently for each +reference. +.Pp +To get an independent handle with its own seek position and settings, +an additional .Xr open 2 -call. -The close-on-exec flag on the new file descriptor is unset. +call must be issued. +.Pq This is not generally possible for pipes and sockets. .Pp -In -.Fn dup2 , -the value of the new descriptor -.Fa newd -is specified. -If this descriptor is already -in use, the descriptor is first deallocated as if a -.Xr close 2 -call had been done first. +The +.Nm dup +call chooses the new descriptor: it is the lowest-numbered descriptor +not currently in use. +The +.Nm dup2 +and +.Nm dup3 +calls allow the caller to choose the new descriptor by passing +.Fa newfd , +which must be within the range of valid descriptors. If -.Fa newd +.Fa newfd +is the same as +.Fa oldfd , +the call has no effect. +Otherwise, if +.Fa newfd +is already in use, it is closed as if +.Xr close 2 +had been called. +.Pp +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 +.Dv STDIN_FILENO , +.Dv STDOUT_FILENO , and -.Fa oldd -are the same, the call has no effect. +.Dv 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 +.Xr getdtablesize 3 +and can to some extent be adjusted with +.Xr setrlimit 2 . .Pp +The .Fn dup3 -behaves exactly like -.Fn dup2 -only it allows extra +call includs an additional .Fa flags -to be set on the returned file descriptor. -The following flags are valid: -.Bl -tag -width O_NONBLOCK -offset indent +argument supporting a subset of the +.Xr open 2 +flags: +.Bl -tag -width O_NOSIGPIPE -offset indent .It Dv O_CLOEXEC -Set the -.Dq close-on-exec -property. +Set the close-on-exec flag on +.Fa newfd . .It Dv O_NONBLOCK Sets non-blocking I/O. .It Dv O_NOSIGPIPE -Return -.Er EPIPE -instead of raising -.Dv SIGPIPE . +For pipes and sockets, do not raise +.Dv SIGPIPE +when a write is made to a broken pipe. +Instead, the write will fail with +.Er EPIPE . .El +As described above, only the close-on-exec flag is +per-file-descriptor, so passing any of the other +.Fa flags +will affect +both +.Fa oldfd +and +.Fa newfd . +These settings are, however, applied atomically along with the rest of +the +.Fn dup3 +operation. +.Pp +In the case of +.Fn dup +and +.Fn dup2 +the close-on-exec flag on the new file descriptor is always left +unset and all the modes and settings of the underlying object are left +unchanged. +.Pp +Functionality similar to +.Fn dup +with slightly different semantics is also available via +.Xr fcntl 2 . .Sh RETURN VALUES -The value \-1 is returned if an error occurs in either call. -The external variable +These calls return the new file descriptor value. +In the case of +.Fn dup2 +and +.Fn dup3 +this is always the same as +.Fa newfd . +If an error occurs, the value \-1 is returned and .Va errno -indicates the cause of the error. +is set to indicate what happened. +.Sh 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 (error handling omitted for +clarity): +.Bd -literal -offset indent +#include \*[Lt]unistd.h\*[Gt] + +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]; +.Ed .Sh ERRORS -All three functions may fail if: +These functions fail if: .Bl -tag -width Er .It Bq Er EBADF -.Fa oldd -is not a valid active descriptor -or -.Fa newd +.Fa oldfd +is not a valid active descriptor, or for +.Fn dup2 +and +.Fn dup3 , +.Fa newfd is not in the range of valid file descriptors. -.El -.Pp -The -.Fn dup -function may also fail if: -.Bl -tag -width Er .It Bq Er EMFILE Too many descriptors are active. -.El -.Pp -The -.Fn dup3 -function will also fail if: -.Bl -tag -width Er +Only +.Fn dup +can generate this error. .It Bq Er EINVAL .Fa flags -is other than -.Dv O_NONBLOCK -or -.Dv O_CLOEXEC . +contained an invalid value. +Only +.Fn dup3 +can generate this error. .El .Sh SEE ALSO .Xr accept 2 , .Xr close 2 , .Xr fcntl 2 , +.Xr getrlimit 2 , .Xr open 2 , .Xr pipe 2 , +.Xr setrlimit 2 , .Xr socket 2 , .Xr socketpair 2 , .Xr getdtablesize 3 @@ -178,5 +239,5 @@ functions conform to .Sh HISTORY The .Fn dup3 -function is inspired from Linux and appeared in +function originated in Linux and appeared in .Nx 6.0 .