Subject: bug#8846: coreutils-8.12 on HP-UX 11.31: 3 of 365 tests failed

From: Stefano Lattarini <[email-masked]>
Date: Tue, 14 Jun 2011 09:34:01 +0200

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