The problem is that select() isn't re-entrant: it gets interrupted by the signal handler and doesn't resume, so you end up with an empty @ready array. That means you fall out of the while (@ready) {} loop; the sub returns, createProcess() is called again, the file handles are re-opened: the previous command is terminated.
To work around that, add a flag variable which gets reset in the handler:my $redo; # flag sub status () { $SIG{USR1} = \&status; print STDERR "Currently running: $StartedProcess\n"; $redo = 1; # re-set flag } # Opens external program, and as long as it exists, checks # if there is data in the pipe (STDOUT/STDERR) sub createProcess () { my($line, $selector, @ready, $fh); $StartedProcess = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, "./external.pp" +); close(CMD_IN); $selector = IO::Select->new(); $selector->add(*CMD_ERR, *CMD_OUT); $redo = 1; # set flag while($redo) { $redo = 0; # clear flag while(@ready = $selector->can_read) { # do some operations on STDOUT/STDERR here } warn "after inner loop\n"; } warn "closing CMD_OUT and CMD_ERR\n"; close(CMD_OUT); close(CMD_ERR); }
Also, you should set up a SIGCHLD handler which clears the $selector after the child is gone.
In reply to Re^8: Signal to parent-process. Does it affect it's children?
by shmem
in thread Signal to parent-process. Does it affect it's children?
by rapide
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |