* doc/autoconf.texi (File Descriptors): Clarify that only the exec builtin suffers from cloexec issues, and consolidate example to show both /bin/sh and ksh pitfalls at once.
Signed-off-by: Eric Blake <ebl...@redhat.com> --- How does this look? ChangeLog | 7 +++++ doc/autoconf.texi | 78 +++++++++++++++++++++++++--------------------------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1fca7bb..c2e11d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-06-13 Eric Blake <ebl...@redhat.com> + + doc: mention more about ksh cloexec behavior + * doc/autoconf.texi (File Descriptors): Clarify that only the exec + builtin suffers from cloexec issues, and consolidate example to + show both /bin/sh and ksh pitfalls at once. + 2011-05-05 Eric Blake <ebl...@redhat.com> doc: document dash bug with positional parameters diff --git a/doc/autoconf.texi b/doc/autoconf.texi index 7ff693f..5571c2c 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -15435,53 +15435,51 @@ File Descriptors Don't rely on file descriptors 0, 1, and 2 remaining closed in a subsidiary program. If any of these descriptors is closed, the operating system may open an unspecified file for the descriptor in the -new process image. Posix says this may be done only if the subsidiary -program is set-user-ID or set-group-ID, but HP-UX 11.23 does -it even for ordinary programs. - -Don't rely on open file descriptors being open in child processes. In -@command{ksh}, file descriptors above 2 which are opened using +new process image. Posix 2008 says this may be done only if the +subsidiary program is set-user-ID or set-group-ID, but HP-UX 11.23 does +it even for ordinary programs, and the next version of Posix will allow +HP-UX behavior. + +If you want a file descriptor above 2 to be inherited into a child +process, then you must use redirections specific to that command or a +containing subshell or command group, rather than relying on +@command{exec} in the shell. In @command{ksh} as well as HP-UX +@command{sh}, file descriptors above 2 which are opened using @samp{exec @var{n}>file} are closed by a subsequent @samp{exec} (such as that involved in the fork-and-exec which runs a program or script). -Thus, using @command{sh}, we have: - -@example -$ @kbd{cat ./descrips} -#!/bin/sh - -echo hello >&5 -$ @kbd{exec 5>t} -$ @kbd{./descrips} -$ @kbd{cat t} -hello -$ -@end example - -@noindent -But using ksh: - -@example -$ @kbd{exec 5>t} -$ @kbd{./descrips} -hello -$ @kbd{cat t} -$ -@end example - -@noindent -Within the process which runs the @samp{descrips} script, file -descriptor 5 is closed. Don't rely on duplicating a closed file descriptor to cause an error. With Solaris @command{/bin/sh}, when the redirection fails, the output goes to the original file descriptor. -@example -$ @kbd{bash -c 'echo hi >&3' 3>&-; echo $?} -bash: 3: Bad file descriptor -1 -$ @kbd{/bin/sh -c 'echo hi >&3' 3>&-; echo $?} -hi -0 +Demonstrating these last two points, note how the child @command{sh} (in +this case, Solaris 10 @command{/bin/sh}) leaks output to standard output +when file descriptor 5 is closed, and how the parent @command{ksh} +refuses to pass file descriptor 5 to the child via @command{exec}: + +@example +$ @kbd{echo 'echo hello >&5\n' >k +$ @kbd{sh -c 'exec 5>t; echo -`sh ./k`-`cat t`-'} +--hello- +$ @kbd{sh -c ':>t; exec 5>&-; echo -`sh ./k`-`cat t`-'} +-hello-- +$ @kbd{ksh -c 'exec 5>t; echo -`ksh ./k`-`cat t`-'} +./k[1]: 5: cannot open [Bad file number] +--- +$ @kbd{ksh -c ':>t; exec 5>&-; echo -`ksh ./k`-`cat t`-'} +./k[1]: 5: cannot open [Bad file number] +--- +$ @kbd{ksh -c '(echo -`ksh ./k`-`cat t`-) 5>t'} +--hello- +$ @kbd{ksh -c '{ echo -`ksh ./k`-`cat t`-; } 5>t'} +--hello- +$ @kbd{ksh -c 'echo -`5>t ksh ./k`-`cat t`-'} +--hello- +$ @kbd{bash -c 'exec 5>t; echo -`bash ./k`-`cat t`-'} +--hello- +$ @kbd{bash -c ':>t; exec 5>&-; echo -`bash ./k`-`cat t`-'} +./k: line 1: 5: Bad file number +--- @end example Fortunately, an attempt to close an already closed file descriptor will -- 1.7.4.4