Eric Blake wrote: > On 06/13/2011 09:37 AM, Jim Meyering wrote: >>> But I think the reason that it invokes a problem is not because of the >>> 1>&$e construct, but because HP-UX opens secondary file descriptors as >>> cloexec or otherwise closing them at some point, so the '/bin/sh k' >>> child process is not inheriting fd 9 from the parent process. >> >> Ah ha! >> That sounds like a syscall that needs to be gnulib-replaced in bash/zsh. >> Of course, first we'd need to gnulib-enable a shell. > > Yep, I've confirmed that both HP-UX and Solaris 10 ksh use CLOEXEC fds > for intermediate fd values created by exec; that POSIX permits (but > fortunately does not require) this behavior, and that autoconf already > documents the pitfall of expecting fds > 2 to be preserved into child > processes: > > http://www.gnu.org/software/autoconf/manual/autoconf.html#File-Descriptors > >> Don't rely on open file descriptors being open in child >> processes. In ksh, file descriptors above 2 which are opened using >> ‘exec n>file’ are closed by a subsequent ‘exec’ (such as that >> involved in the fork-and-exec which runs a program or script). Thus, >> using sh, we have: >> >> $ cat ./descrips >> #!/bin/sh - >> echo hello >&5 >> $ exec 5>t >> $ ./descrips >> $ cat t >> hello >> $ >> >> But using ksh: >> >> $ exec 5>t >> $ ./descrips >> hello >> $ cat t >> $ > > On Solaris 10, truss shows this for 'exec 9>&2': > > dup(2) = 3 > close(9) Err#9 EBADF > fcntl(3, F_DUPFD, 0x00000009) = 9 > close(3) = 0 > fcntl(9, F_SETFD, 0x00000001) = 0 > >> tusc (11+, freeware) > > Likewise on HP-UX 11.31, tusc shows: > > dup(2) ................................................... = 3 > close(9) ................................................. ERR#9 EBADF > fcntl(3, F_DUPFD, 9) ..................................... = 9 > close(3) ................................................. = 0 > fcntl(9, F_SETFD, 1) ..................................... = 0 > > About the only thing I can think of is to pass the details about the > desired redirection as a command-line or env-var setting, to be done by > the script itself, rather than relying on the parent shell (the one in > make) being able to do a redirection that persists into the child (the > one sourcing init.sh).
Thanks for confirming. Actually the fix (at least for bourne shell scripts) is even easier than that: perform the redirection from init.sh's setup_ function I'm going to revert (in coreutils) my eval-adding change, and then apply this instead: >From d987cf87de5e7e597e295914c536bd332c24cc63 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Mon, 13 Jun 2011 18:54:53 +0200 Subject: [PATCH] init.sh: redirect FD 9 to stderr again, for Solaris 10 and HP-UX * tests/init.sh (setup_): When $stderr_fileno_ is not 2, redirect it. Prior to this change, we would redirect before the shell fork-and-exec performed via automake's TESTS_ENVIRONMENT, but that redirection was ineffective on Solaris 10 and HP-UX 11.31, due to the fact that those systems set the CLOEXEC bit on FDs larger than 2. Thus our redirection of FD 9 would not survive the fork-and-exec of running each test script. --- tests/init.sh | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/tests/init.sh b/tests/init.sh index 60d1bc1..d101643 100644 --- a/tests/init.sh +++ b/tests/init.sh @@ -317,6 +317,11 @@ path_prepend_ () setup_ () { + # If we're redirecting a file descriptor larger than 2, say via automake's + # TESTS_ENVIRONMENT, that redirected FD is closed-on-exec on some systems + # (at least Solaris 10 and HP-UX 11.x), so redirect it here again. + test $stderr_fileno_ = 2 || eval "exec $stderr_fileno_>&2" + if test "$VERBOSE" = yes; then # Test whether set -x may cause the selected shell to corrupt an # application's stderr. Many do, including zsh-4.3.10 and the /bin/sh -- 1.7.6.rc0.293.g40857