Subject: Re: bug#16940: [PATCH] tests: Do not access /dev/tty if it does not exist

From: Pádraig Brady <[email-masked]>
Date: Wed, 05 Mar 2014 15:21:37 +0000

On 03/05/2014 09:17 AM, Bernhard Voelker wrote:
> On 03/05/2014 05:20 AM, Pádraig Brady wrote:
>>    if test -w /dev/full && test -c /dev/full &&
>>       test -w /dev/tty && test -c /dev/tty; then
> 
> This looks right.
> However, I'm wondering why the 'test -t 1' right after
> the exec redirection didn't already catch this:

Good point.

>   if test -w /dev/full && test -c /dev/full; then
>   (
>     exec >/dev/tty
>     test -t 1 || exit 0
>     nohup echo hi 2> /dev/full
>     test $? = 125 || fail=1
>     test -f nohup.out || fail=1
>     test -s nohup.out && fail=1
>     rm -f nohup.out
>     exit $fail
>   ) || fail=1
>   fi
> 
> Does someone have a test log file with the failure?

Ondřej Vašík ran the rawhide build again producing:

  ./tests/misc/nohup.sh: line 66: /dev/tty: No such device or address
  + fail=1

So exec >/dev/tty is throwing ENXIO and exiting the subshell.
ENXIO is fine and corresponds to the process not having a controlling tty.

I guessed the change here is with the newly released bash 4.3
which is exiting the subshell immediately in this case, and confirmed
the following fails:

  setsid make SHELL=~/bash-4.3/bash TESTS=tests/misc/nohup.sh SUBDIRS=. check

Now reducing the case and comparing different shells we get:

  $ setsid bash --posix -c 'echo $BASH_VERSION; (exec >/dev/tty; exit 0) || echo failed_early'
  4.2.45(1)-release
  bash: /dev/tty: No such device or address

  $ setsid ./bash --posix -c 'echo $BASH_VERSION; (exec >/dev/tty; exit 0) || echo failed_early'
  4.3.0(1)-release
  ./bash: /dev/tty: No such device or address
  failed_early

  $ setsid ksh -c '(exec >/dev/tty; exit 0) || echo failed_early'
  $ ksh: /dev/tty: cannot create [No such device or address]
  failed_early

  $ setsid dash -c '(exec >/dev/tty; exit 0) || echo failed_early'
  dash: 1: cannot create /dev/tty: No such device or address
  failed_early

So rather than newer bash being the difference here,
it's the older bash that is the outlier.
So we should adjust the test case to handle all shells.
Proposed patch attached.

thanks,
Pádraig.
>From 76bd83186496b3ed45adef598c1eab9797852d47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email-masked]>
Date: Wed, 5 Mar 2014 15:14:07 +0000
Subject: [PATCH] tests: fix false failure in nohup.sh in non tty builds

* tests/misc/nohup.sh: When building without a controlling tty,
an exec failure is triggered in a subshell, which causes POSIX
shells to immediately exit the subshell.  This was brought
to notice by the newly conforming bash 4.3.
Fixes http:/bugs.gnu.org/16940
---
 tests/misc/nohup.sh |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/tests/misc/nohup.sh b/tests/misc/nohup.sh
index 6d2b515..015e84f 100755
--- a/tests/misc/nohup.sh
+++ b/tests/misc/nohup.sh
@@ -63,6 +63,11 @@ rm -f nohup.out err
 # to stderr must be fatal.  Requires stdout to be terminal.
 if test -w /dev/full && test -c /dev/full; then
 (
+  # POSIX shells immediately exit the subshell on exec error.
+  # So check we can write to /dev/tty before the exec, which
+  # isn't possible if we've no controlling tty for example.
+  >/dev/tty || exit 0
+
   exec >/dev/tty
   test -t 1 || exit 0
   nohup echo hi 2> /dev/full
-- 
1.7.7.6