Question

$ perl5.8 -w -e 'if (my $pid=open(my $P, "|-")) {
      kill("SIGKILL",$pid); sleep(2); print $P "test1:$pid\n";}; '
Broken pipe

Now I'm trying to catch that broken pipe

$ perl5.8 -w -e '$SIG{PIPE} = sub {print "SIGPIPE\n";return 1}; 
   if (my $pid=open(my $P, "|-")) {
      kill("SIGKILL",$pid); sleep(2); print $P "test1:$pid\n"}; 
$

Nothing at all is printed when I would have expected SIGPIPE. It seems as if it treats my anonymous sub handler as if it was IGNORE instead.

  • Pretty much any content of the sub does not produce any effect (print, die, change package variable value)

  • The code doesn't die; if you print something to STDOUT in the end it will print.

What am I missing?


UPDATE : @jm666's answer led me to the issue: the pipe's writes were not flushed; and as such it was too early to get the SIGPIPE. Adding autoflush helped:

$ perl5.8 -w -e 'use IO::Handle ;$SIG{PIPE} = sub {print "SIGPIPE\n"}; 
   if (my $pid=open(my $P, "|-")) {
   $P->autoflush(1);
   kill(SIGTERM,$pid); sleep(2);;print $P "test1:$pid\n"}; '

SIGPIPE
$
Was it helpful?

Solution

Physical writes to pipes are delayed, so you can catch them on the close. the next prints the message. (added the close $P)

perl -w -e '$SIG{PIPE} = sub {print "SIGPIPE\n";return 1}; if (my $pid=open(my $P, "|-")) { kill("SIGKILL",$pid); sleep(2); print $P "test1:$pid\n";close $P};'

more: http://perldoc.perl.org/perlipc.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top