in reply to How to end a process started with open "cmd |" before it has output

The strace utility shows that, with child.pl's print omitted, main.pl is stuck in the wait4() system call, waiting for child.pl to exit and emit SIGCHLD. It seems that child.pl is not receiving SIGPIPE under those circumstances (proof below). Perhaps child.pl does not set up its end of the pipe, having nothing to say.

With the print statement in, strace shows that child.pl exits with SIGPIPE, just the way we expect.

Changing child.pl to,

#!/usr/bin/perl $SIG{PIPE} = sub { die 'SIGPIPE received' }; $| = 1; sleep 10; # print "x\n"; while (1) { sleep 10; }
does not change the behavior, so SIGPIPE is not received by child.pl. Restoring the print line yields the message,
$ ./main.pl
SIGPIPE received at ./child.pl line 2.
$ 

As ysth suggests, you could kill the child explicitly with SIGINT.

After Compline,
Zaxo

  • Comment on Re: How to end a process started with open "cmd |" before it has output
  • Download Code

Replies are listed 'Best First'.
Re: Re: How to end a process started with open "cmd |" before it has output
by ysth (Canon) on May 07, 2004 at 06:25 UTC
    Yes, SIGPIPE doesn't just occur asynchronously; the process that receives it usually has to try to use the broken pipe before getting it. (Exceptions are sockets with SO_KEEPALIVE set and explicit kills by other processes.)

    Think of it as libc's way of generating a fatal error.