If I have a long-running system
command like apt-cache search <some query>
, is there a way to forward a SIGINT
sent via ^C
on the command line to the parent Perl process in such a way that all child processes are reaped.
This example does not have the desired behavior. The signal is sent to the child process.
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use autodie;
# long running command on ubuntu, produces a ton of output.
# replace with your favorite long running command
system("apt-cache search hi");
print("Perl did not catch SIGINT even with autodie\n");
I tried searching around for ways of capturing the pid of the child that would be created by system("apt-cache search hi &")
, but couldn't find any, so I tried fork
ing and exec
ing the process and writing a signal handler. This doesn't work because apt-cache
itself launches a few processes via the clone
system call. Hand-rolling some logic to walk part of the process tree and clean up the
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use autodie;
my $cpid;
$SIG{INT} = sub {
kill 'KILL', $cpid;
exit;
};
# long running command on ubuntu, produces a ton of output.
# replace with your favorite long running command
$cpid = fork;
if ($cpid == 0) {
exec 'apt-cache', 'search', 'hi';
}
print "Perl did not catch SIGINT even with autodie\n";
I guess essentially what I want is either a way of determining whether a child process launched by system
exited due to a signal like SIGINT
so I can have the Perl script clean up after itself or a way of walking the child processes and reaping them in such a way that strange edge cases of process management are handled cleanly and portably.