lib/PublicInbox/Spawn.pm | 8 +++++--- lib/PublicInbox/SpawnPP.pm | 7 ++++++- t/spawn.t | 2 +- diff --git a/lib/PublicInbox/Spawn.pm b/lib/PublicInbox/Spawn.pm index 66dce3353e3bd872fad51838a53200bf94f50632..83730302a00ba126d435f63f359511a08e89b89a 100644 --- a/lib/PublicInbox/Spawn.pm +++ b/lib/PublicInbox/Spawn.pm @@ -104,9 +104,11 @@ REDIR(in, 0); REDIR(out, 1); REDIR(err, 2); for (sig = 1; sig < NSIG; sig++) - signal(sig, SIG_DFL); /* ignore errorrs on signals */ - ret = sigprocmask(SIG_SETMASK, &old, NULL); - if (ret != 0) xerr("sigprocmask failed in vfork child"); + signal(sig, SIG_DFL); /* ignore errors on signals */ + /* + * don't bother unblocking, we don't want signals + * to the group taking out a subprocess + */ execve(filename, argv, envp); xerr("execve failed"); } diff --git a/lib/PublicInbox/SpawnPP.pm b/lib/PublicInbox/SpawnPP.pm index fe95d1269c210efb35720fd4d24584ac3eac101c..36223e8132eefa30c380bf1b07fef42bbf40628b 100644 --- a/lib/PublicInbox/SpawnPP.pm +++ b/lib/PublicInbox/SpawnPP.pm @@ -3,11 +3,15 @@ # License: AGPL-3.0+ 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 $pid = fork; if ($pid == 0) { if ($in != 0) { @@ -29,6 +33,7 @@ exec @$cmd; die "exec $cmd->[0] failed: $!\n"; } } + sigprocmask(SIG_SETMASK, $old) or die "can't unblock signals: $!"; $pid; } diff --git a/t/spawn.t b/t/spawn.t index 9e58f675fe2a8fd140e7dd96982d1e639cbd674b..0f756462d02999831eff5307a87a8312acc419ca 100644 --- a/t/spawn.t +++ b/t/spawn.t @@ -87,7 +87,7 @@ ok(defined $pid && $pid > 0, 'returned pid when array requested'); is(kill(0, $pid), 1, 'child process is running'); ok(!defined(sysread($fh, my $buf, 1)) && $!{EAGAIN}, 'sysread returned quickly with EAGAIN'); - is(kill(15, $pid), 1, 'child process killed early'); + is(kill(9, $pid), 1, 'child process killed early'); is(waitpid($pid, 0), $pid, 'child process reapable'); isnt($?, 0, '$? set properly: '.$?); }