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

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

Replies are listed 'Best First'.
Re^5: Child process dies
by polettix (Vicar) on Jan 05, 2007 at 23:58 UTC
    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.