[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:1.8.1.19) Gecko/20081209 Thunderbird/2.0.0.19 Mnenhy/0.7.6.666 |
-----BEGIN PGP SIGNED MESSAGE-----
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
8.11.0
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
-----BEGIN PGP SIGNATURE-----
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
iEYEARECAAYFAkmt3eEACgkQ84KuGfSFAYChugCeP6xsbWi7/kigpIx4tXv2tWJP
ESgAoKhrga8qqEh/Nqkpctpta/6cB0rq
=yrN3
-----END PGP SIGNATURE-----