Notice: this is a JFTR answer; for the final solution of the issue, see the better working solution at: <http://lists.gnu.org/archive/html/bug-coreutils/2011-06/msg00080.html> <http://lists.gnu.org/archive/html/bug-autoconf/2011-06/msg00016.html>
On Tuesday 14 June 2011, Eric Blake wrote: > On 06/13/2011 04:24 PM, Stefano Lattarini wrote: > > On Monday 13 June 2011, Eric Blake wrote: > >> > >> Not possible to portably sniff out closed fds; quoting the autoconf manual: > >> > >>> 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. > >> > > Do the shells with the close-on-exec issue also suffer of the issue with > > closed fds you've reported? If not, the following could be enough to > > solve our situation without having to change automake: > > Where are you proposing this hack? In init.sh (after fd 9 has already > been closed if the calling shell used exec instead of some other form of > redirection)? That is, why are we trying to fix init.sh to deal with a > closed fd after the fact, when it seems like the better approach is to > guarantee that fd is never closed on exec in the first place? Which > necessarily implies altering the caller. > > > > > if (exec 3>&-; exec 4>&3) >/dev/null 2>&1; then > > # Cannot determine whether a file descriptor is closed, fall back > > # to inferior hack. > > if test 2 -ne "$stderr_fileno_" && test ! -t "$stderr_fileno_"; then > > eval "exec $stderr_fileno_>&2" # Or is `stderr_fileno_=2' enough? > > fi > > Or is the whole point of this hack to init.sh to avoid the spurious > warning about EBADF and to instead redirect errors to the > (possibly-altered-by-make) fd 2 when fd 9 was lost, so that at least the > warning messages appear in the logs even though we lost the chance to > display them on the tty? > Yes, this was the idea. But it is moot now that we have a better solution to be used in TESTS_ENVRIRONMENT. > At any rate, in answer to your question: > > Solaris /bin/sh (the shell where failed redirections are silently > ignored) does this: > > $ /bin/sh -c '(exec 3>&-; exec 4>&3) >/dev/null 2>&1; echo $?' > 0 > $ cat k > #!/bin/sh > e=9; warn_ () { echo "$@" 1>&$e; }; warn_ x > $ /bin/sh k > x > $ /bin/sh k >/dev/null > $ /bin/sh k 9>&2 > x > $ /bin/sh k 9>&2 >/dev/null > x > > That is, if fd 9 is closed, then 1>&$e (aka >&9) is a no-op on that > shell, and output goes to the original fd 1; but if fd 9 is open, then > output goes to fd 9. > > Whereas ksh and HP-UX sh are both vocal on failed redirections, for > reliable detection: > > $ ksh -c '(exec 3>&-; exec 4>&3) >/dev/null 2>&1; echo $?' > 1 > $ ksh k > k[2]: 9: cannot open [Bad file number] > $ ksh k >/dev/null > k[2]: 9: cannot open [Bad file number] > $ ksh k 9>&2 > x > $ ksh k 9>&2 >/dev/null > x > This would have been a problem :-/ Luckily, no more need to worry about it now :-) Regards, Stefano