in reply to Re^2: Child process dies
in thread Child process dies

IIRC the SIGPIPE signal should be sent only when the one end tries to do I/O on a pipe that is closed on the other end. Moreover... why sleep 1 for 1 .. 100; instead of sleep 100;?

Flavio
perl -ple'$_=reverse' <<<ti.xittelop@oivalf

Don't fool yourself.

Replies are listed 'Best First'.
Re^4: Child process dies
by johngg (Canon) on Jan 05, 2007 at 20:11 UTC
    Why the sleep 1 for 1 .. 100;? My ignorance really; I wasn't sure whether the script, like my daughter, would sleep through the alarm so I decided to try lots of small sleeps after it didn't work with one long sleep.

    I was already trying things like explicitly closing the pipe in the parent if it caught a signal. Following your post I have modified the script so the child keeps printing a "heartbeat" to the pipe but still to no avail. Here's the modified script.

    use strict; use warnings; use IO::Pipe; my $pipeFH; my $rcHandler = sub {$pipeFH->close(); exit;}; $SIG{INT} = $rcHandler; $SIG{QUIT} = $rcHandler; $SIG{TERM} = $rcHandler; print qq{Parent PID $$\n}; $pipeFH = IO::Pipe->new(); my $pid; if ($pid = fork) { $pipeFH->reader(); print qq{Kid is PID $pid\n}; } elsif(defined($pid)) { $SIG{PIPE} = sub {exit;}; $pipeFH->writer(); $pipeFH->print(qq{Kid: Snoozing\n}); for my $heartbeat ( 1 .. 30 ) { $pipeFH->print(qq{Kid: Heartbeat $heartbeat\n}); sleep 1; } $pipeFH->print(qq{Kid: Waking\n}); print qq{Kid: Quitting\n}; exit; } while ((my $returnPid = wait) != -1) { print qq{Kid $returnPid returned\n}; } while (defined(my $line = $pipeFH->getline())) { print qq{Read: $line}; }

    I had been killing the parent with a kill -15 (TERM) from another shell but I noticed that the child does go away immediately if I Ctrl-C the running parent. Is it the case that child processes also get an INT if the parent gets one from the shell?

    Cheers,

    JohnGG

      Update In the code below the main difference with respect to johngg's version is the use of the straight pipe function instead of IO::Pipe. It turned out (thanks to johngg's tests) that using straight pipes allowed him to trap the PIPE signal, which he couldnt' using the module. I tried to peek into the module and found nothing about SIGPIPE trapping, but I didn't dig this up to the modules included by IO::Pipe.

      Linux box with a slightly modified version of your script, and the parent signalled from another shell:

      #!/usr/bin/perl use strict; use warnings; my $whoami; sub handler { print {*STDERR} "$whoami: handler [@_]\n"; exit 0; } $SIG{INT} = \&handler; $SIG{QUIT} = \&handler; $SIG{TERM} = \&handler; $SIG{PIPE} = \&handler; END { print {*STDERR} "$whoami in END block\n"; } print {*STDERR} qq{Parent PID $$\n}; pipe my $r, my $w; my $pid; if ($pid = fork) { $whoami = 'parent'; close $w; print {*STDERR} qq{Kid is PID $pid\n}; while (<$r>) { print {*STDERR} "parent received: $_"; } print {*STDERR} "parent exiting normally\n"; exit 0; } ## end if ($pid = fork) elsif (defined($pid)) { select $w; $|++; $whoami = 'kid'; close $r; print {$w} qq{Kid: Snoozing\n}; for my $heartbeat (1 .. 30) { print {$w} qq{Kid: Heartbeat $heartbeat\n}; sleep 1; } print {$w} qq{Kid: Waking\n}; print {*STDERR} qq{Kid: Quitting\n}; exit; } ## end elsif (defined($pid)) __END__ poletti@PolettiX:~/sviluppo/perl$ perl johngg.pl Parent PID 5336 Kid is PID 5337 parent received: Kid: Snoozing parent received: Kid: Heartbeat 1 parent received: Kid: Heartbeat 2 parent received: Kid: Heartbeat 3 parent received: Kid: Heartbeat 4 parent received: Kid: Heartbeat 5 parent: handler [TERM] parent in END block poletti@PolettiX:~/sviluppo/perl$ kid: handler [PIPE] kid in END block

      Note that after the parent exits the shell regains control, hence the prompt. Within a second, the kid is trying to write to the pipe and gets signalled. Also note the following run (stopped with CTRL-C):

      poletti@PolettiX:~/sviluppo/perl$ perl johngg.pl Parent PID 5348 Kid is PID 5349 parent received: Kid: Snoozing parent received: Kid: Heartbeat 1 parent received: Kid: Heartbeat 2 parent received: Kid: Heartbeat 3 parent: handler [INT] parent in END block kid: handler [INT] kid in END block

      Both processes get the INT signal: probably the shell sends the signal to the whole process group.

      Flavio
      perl -ple'$_=reverse' <<<ti.xittelop@oivalf

      Don't fool yourself.