ipc-system-simple
ipc-system-simple copied to clipboard
IPC::System::Simple can return "No child processes" (ECHILD) when $SIG{CHLD} is set.
(This issue was originally reported on Jun 05 2009 by [email protected] as https://rt.cpan.org/Ticket/Display.html?id=46684. Transferring it to the current issue tracker.)
Due to the way in which Perl internally handles the reaping of child
processes, the presence of a $SIG{CHLD}
can prevent IPC::System::Simple
from gaining access to return information, which then causes it to throw
an exception claiming that it can't start the program, with No child processes
as the reason why. Eg:
#!/usr/bin/perl -w
use strict;
use IPC::System::Simple qw(run);
use POSIX;
$SIG{CHLD} = sub { while (waitpid(-1,WNOHANG) > 0) { } };
run("echo hello world");
This looks like it may be hard to fix, but can be worked around by temporarily unsetting the signal handler:
#!/usr/bin/perl -w
use strict;
use IPC::System::Simple qw(run);
use POSIX;
$SIG{CHLD} = sub { while (waitpid(-1,WNOHANG) > 0) { } };
{
local $SIG{CHLD} = 'DEFAULT';
run("echo hello world");
}
The only gotcha here is that if your existing signal handler actually did something important, then we're breaking it for the duration of our local block. If the existing signal handler was merely making sure child processes get reaped (which is usually the case), then the code above is harmless.
Current behavior (tested on perl-5.14 and 5.30):
$ cat rtc-46684-sig-child.pl
#!/usr/bin/perl -w
use strict;
use IPC::System::Simple qw(run);
use POSIX;
# https://rt.cpan.org/Ticket/Display.html?id=46684
$SIG{CHLD} = sub { while (waitpid(-1,WNOHANG) > 0) { } };
{
local $@;
eval { run("echo hello world"); };
print "$@\n" if $@;
}
print "Finished\n";
$ perl rtc-46684-sig-child.pl
hello world
"echo hello world" failed to start: "" at rtc-46684-sig-child.pl line 12.
Finished