pjf / ipc-system-simple

Perl module to make running system commands and capturing errors as simple as possible.

Home Page:http://search.cpan.org/perldoc?IPC::System::Simple

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IPC::System::Simple can return "No child processes" (ECHILD) when $SIG{CHLD} is set.

jkeenan opened this issue · comments

(This issue was originally reported on Jun 05 2009 by PJF@cpan.org 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