lib/PublicInbox/Spawn.pm | 18 +++++++++++++++++- diff --git a/lib/PublicInbox/Spawn.pm b/lib/PublicInbox/Spawn.pm index 23f303fbe182ee7968f6ca6ff6c1486498fe1f61..c5a5c01223a6461b5ff13daf186241178f2f6344 100644 --- a/lib/PublicInbox/Spawn.pm +++ b/lib/PublicInbox/Spawn.pm @@ -24,6 +24,8 @@ #include #include #include #include +#include +#include #define AV_ALLOCA(av, max) alloca((max = (av_len((av)) + 1)) * sizeof(char *)) @@ -81,6 +83,8 @@ const char *filename = SvPV_nolen(file); pid_t pid; char **argv, **envp; I32 max; + sigset_t set, old; + int ret; argv = AV_ALLOCA(cmd, max); av2c_copy(argv, cmd, max); @@ -88,14 +92,26 @@ envp = AV_ALLOCA(env, max); av2c_copy(envp, env, max); + ret = sigfillset(&set); + assert(ret == 0 && "BUG calling sigfillset"); + ret = sigprocmask(SIG_SETMASK, &set, &old); + assert(ret == 0 && "BUG calling sigprocmask to block"); pid = vfork(); if (pid == 0) { + int sig; + 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"); execve(filename, argv, envp); xerr("execve failed"); } + ret = sigprocmask(SIG_SETMASK, &old, NULL); + assert(ret == 0 && "BUG calling sigprocmask to restore"); return (int)pid; } @@ -111,7 +127,7 @@ eval { my $f = "$inline_dir/.public-inbox.lock"; open my $fh, '>', $f or die "failed to open $f: $!\n"; flock($fh, LOCK_EX) or die "LOCK_EX failed on $f: $!\n"; - eval 'use Inline C => $vfork_spawn'; + eval 'use Inline C => $vfork_spawn'; #, BUILD_NOISY => 1'; my $err = $@; flock($fh, LOCK_UN) or die "LOCK_UN failed on $f: $!\n"; die $err if $err;