[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ignored SIGPIPE (Darwin vs. cat)

From: Eric Blake
Subject: Re: ignored SIGPIPE (Darwin vs. cat)
Date: Tue, 03 Mar 2009 18:48:17 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20081209 Thunderbird/ Mnenhy/

Hash: SHA1

According to Bruno Haible on 3/3/2009 5:37 PM:
> Eric Blake wrote:
>> When running test-closein.sh, I'm getting spurious output on Darwin:
>> cat: standard output: Bad file descriptor
>> PASS: test-closein.sh
> How to reproduce?

$ uname -r
corresponds to Mac OS X 10.4.11

> On Darwin 7 and 9 (MacOS X 10.3.x and 10.9.x) I reproduce an
> error from
>   $ cat foo | :
> or
>   $ { sleep 1; cat foo; } | :
> only if I previously issued the command
>   $ trap '' SIGPIPE

I made sure that SIGPIPE is not ignored when I log in (since POSIX states
that shells are not allowed to re-enable a signal that they inherited in
the ignored state).  My shell is bash 3.2.39.  I can post ktrace/kdump
output, if you are interested (although it gets rather long).

$ seq 10000 | :
$ (trap '' PIPE; seq 10000 | :)
seq: write error: Broken pipe

But the failure I'm seeing is EBADF, not EPIPE:

$ cat foo | :
cat: standard output: Bad file descriptor

and unaffected by SIGPIPE:

$ (trap '' PIPE; cat foo | :)
cat: standard output: Bad file descriptor

>> -# Test for lack of error on pipe
>> -cat ${p}in.tmp | ./test-closein${EXEEXT} || exit 1
>> +# Test for lack of error on pipe.  Ignore any EPIPE failures from cat.
>> +cat ${p}in.tmp 2>/dev/null | ./test-closein${EXEEXT} || exit 1
> Changes like this reduce the reliability and debuggability of shell scripts,
> because you throw away *all* kinds of error output. If there was a typo
> in the word 'cat', or the program did not find its shared libraries, or
> is symlinks to an /etc/alternatives/cat which is misconfigured, or similar
> general errors, we *want* to see the error message.

We are testing how ./test-closein behaves when its stdin is a pipe.  We
don't care what happened on the other end of the pipe, since test-closein
doesn't even validate what it read.  All we care about is that
test-closein doesn't complain about failure to seek on stdin, and doesn't
complain when closing stdin.

> Is the situation where SIGPIPE is ignored a recurrent one?

It looks like the bug is worse than SIGPIPE - it really is the Darwin
kernel closing the read end of the pipe, such that the write end gets
EBADF instead of EPIPE or SIGPIPE.

> I would prefer to add a
> catch-all clause to the beginning of all tests which use pipes:
>   #!/bin/sh
>   if trap | grep "^trap -- ['\"]['\"] SIGPIPE\$" > /dev/null; then
>     echo "Skipping test: SIGPIPE is ignored"
>     exit 77
>   fi

That won't necessarily help - a shell that inherits an ignored SIGPIPE,
rather than having an explicitly user-ignored situation, is under no
obligation to report that fact during 'trap -p'.  And you can often write
tests in such a way that you can guarantee the reader will consume all
input until the writer has completed, rather than completing early, to
avoid the issue of whether SIGPIPE is ignored.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org


reply via email to

[Prev in Thread] Current Thread [Next in Thread]