diff options
Diffstat (limited to 'lib/PublicInbox/SpawnPP.pm')
-rw-r--r-- | lib/PublicInbox/SpawnPP.pm | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/lib/PublicInbox/SpawnPP.pm b/lib/PublicInbox/SpawnPP.pm index dc2ef364..179aba5e 100644 --- a/lib/PublicInbox/SpawnPP.pm +++ b/lib/PublicInbox/SpawnPP.pm @@ -3,12 +3,21 @@ package PublicInbox::SpawnPP; use strict; use warnings; -use POSIX qw(dup2); +use POSIX qw(dup2 :signal_h); # Pure Perl implementation for folks that do not use Inline::C sub public_inbox_fork_exec ($$$$$$) { my ($in, $out, $err, $f, $cmd, $env) = @_; + my $old = POSIX::SigSet->new(); + my $set = POSIX::SigSet->new(); + $set->fillset or die "fillset failed: $!"; + sigprocmask(SIG_SETMASK, $set, $old) or die "can't block signals: $!"; + my $syserr; my $pid = fork; + unless (defined $pid) { # compat with Inline::C version + $syserr = $!; + $pid = -1; + } if ($pid == 0) { if ($in != 0) { dup2($in, 0) or die "dup2 failed for stdin: $!"; @@ -19,9 +28,18 @@ sub public_inbox_fork_exec ($$$$$$) { if ($err != 2) { dup2($err, 2) or die "dup2 failed for stderr: $!"; } - exec qw(env -i), @$env, @$cmd; - die "exec env -i ... $cmd->[0] failed: $!\n"; + + if ($ENV{MOD_PERL}) { + exec qw(env -i), @$env, @$cmd; + die "exec env -i ... $cmd->[0] failed: $!\n"; + } else { + local %ENV = map { split(/=/, $_, 2) } @$env; + exec @$cmd; + die "exec $cmd->[0] failed: $!\n"; + } } + sigprocmask(SIG_SETMASK, $old) or die "can't unblock signals: $!"; + $! = $syserr; $pid; } |