Perl forwards SIGINT to the parent process from the `system` command

If I have a long system command, such as apt-cache search <some query> , there is a way to forward the SIGINT sent via ^C on the command line to the parent Perl process, so that all the child processes are obtained.

There is no desired behavior in this example. 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 to find ways to get the pid of the child element that was created by the system("apt-cache search hi &") , but could not find it, so I tried the fork ing and exec process and the signal capture handler. This does not work because apt-cache itself starts several processes through the clone system call. Rewinding some logic to go through part of the process tree and clear

 #!/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 assume that, in fact, I want to determine if the child process that started using system due to a signal like SIGINT so that I can clear the Perl script after myself or by walking the child processes and reaping them in such a way that weird marginal process control cases are handled cleanly and portable.

+5
source share
1 answer

Make a child node of the process group, then send a signal to the entire process group.

 #!/usr/bin/perl use strict; use warnings; use autodie; use POSIX qw( setpgid ); my $child_pid; $SIG{INT} = sub { kill INT => -$child_pid if $child_pid; exit(0x80 | 2); # 2 = SIGINT }; my $child_pid = fork(); if (!$child_pid) { setpgid($$); exec 'apt-cache', 'search', 'hi'; } WAIT: { no autodie; waitpid($child_pid, 0); redo WAIT if $? == -1 and $!{EINTR}; die $! if $? == -1; } exit( ( $? >> 8 ) | ( 0x80 | ( $? & 0x7F ) ) ); 
+6
source

Source: https://habr.com/ru/post/1239161/


All Articles