On Wed, Aug 19, 2009 at 07:07:59PM +0200, Roland Mainz wrote:
> Danek Duvall wrote:
> > Roland Mainz wrote:
> > > Roland Mainz wrote:
> > > > Does anyone know in which conditions "cat" may return an exit code of
> > > > "141" when writing to a FIFO ?
> > >
> > > The question wasn't 100% correct. It should be: In which conditions can
> > > the statement "cat foo.txt >myfifo" return an exit code of "141" (e.g.
> > > either "cat" or the redirection seems to fail but I am not sure (since I
> > > am doing remote debugging via email... ;-( )) ?
> >
> > The exit code indicates that the process caught SIGPIPE. And write(2) says
> > that SIGPIPE will be sent to a process that tries to write to a pipe or
> > fifo that isn't open for reading by any process. But I presume you knew
> > that.
>
> Right... I hoped that someone knows a more obsure condition which may
> trigger this exit code...
cat reads as much as it can, then it writes as much as it can. So if
the pipe's reader exits after reading only a bit, and cat is done
writing, then no error:
(cat /etc/inet/hosts > /tmp/myfifo; echo $?) &
head /tmp/myfifo
will show that cat exits with status 0.
This should cause exit status 141, but I don't see it:
% (trap "print got SIGPIPEd" PIPE; i=0
while :
do
print $i
((i+=1))
sleep 1
done | cat > /tmp/f; print cat exit: $?) &
[3] 4236
% head /tmp/f
0
1
2
3
4
5
6
7
8
9
[2] - (i=0;while :;do;print $i;((i+=1));sleep
1;done | cat > /tmp/f; print cat exit: $?) &
% cat: write error [Broken pipe]
cat exit: 269
Maybe because I'm using ksh93? Why, yes -- this is what I get using
/usr/has/bin/sh:
% i=0
% (
> while :
> do
> echo $i
> i=`expr $i + 1`
> sleep 1
> done | /bin/cat > /tmp/f ; echo cat exit: $? ) &
4254
% head /tmp/f
0
1
2
3
4
5
6
7
8
9
% Broken Pipe
cat exit: 141
If I try the ksh93 example again without the trap on SIGPIPE then I
don't get the "cat exit: ..." message because ksh93 gets the SIGPIPE and
dies before ever printing it. But if I ignore SIGPIPE then cat ignores
it too and does exit(1) after getting EPIPE from write(2).
OK, so let's throw truss in the picture:
% (i=0;while :;do;print $i;((i+=1));sleep 1;done | truss -o /tmp/t2 -f all -v
all -s all -f cat > /tmp/f; print cat exit: $?) &
% head /tmp/f
0
1
2
3
4
5
6
7
8
9
[2] - Done (i=0;while :;do;print $i;((i+=1));sleep
1;done | truss -o /tmp/t2 -f all -v all -s all -f cat > /tmp/f; print
cat exit: $?) &
% cat exit: 0
% egrep -i 'pipe|exec|exit' /tmp/t2
4303: execve("/usr/bin/cat", 0x080471D4, 0x080471DC) argc = 1
4303: mmap(0x00000000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON, -1, 0) = 0xBFF90000
4303: mmap(0x00010000, 24576, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON|MAP_ALIGN, -1, 0) = 0xBFE20000
4303: mmap(0x00000000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON, -1, 0) = 0xBFE10000
4303: write(1, " 1 0\n", 3) Err#32 EPIPE
4303: Received signal #13, SIGPIPE [default]
%
So how come I got exit status 0? I'm all confused, and off to lunch.
> I don't know... half of the issue is that I am doing remote debugging
> via email and can't replicate the condition on my machine... ;-(
It's easy to replicate with a Bourne shell (see above). I've yet to
replicate using ksh93.
Nico
--