about summary refs log tree commit homepage
path: root/lib/PublicInbox/SpawnPP.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2021-02-07 08:51:46 +0000
committerEric Wong <e@80x24.org>2021-02-07 22:56:56 +0000
commitff36e076103eef2713895fcb4b401f129ae4b6de (patch)
tree72b935ebcd674c5fc6d3fb7c4443749e68c1031e /lib/PublicInbox/SpawnPP.pm
parent3894c29d99646fcd315ca6794b65e32547fcbae2 (diff)
downloadpublic-inbox-ff36e076103eef2713895fcb4b401f129ae4b6de.tar.gz
The default $SIG{__DIE__} inside a forked child doesn't actually
do what we want it to do.  We don't want it to zip up the stack
the parent used, but instead want to exit the child process
after warning.
Diffstat (limited to 'lib/PublicInbox/SpawnPP.pm')
-rw-r--r--lib/PublicInbox/SpawnPP.pm20
1 files changed, 9 insertions, 11 deletions
diff --git a/lib/PublicInbox/SpawnPP.pm b/lib/PublicInbox/SpawnPP.pm
index 401cb78d..2c5edef6 100644
--- a/lib/PublicInbox/SpawnPP.pm
+++ b/lib/PublicInbox/SpawnPP.pm
@@ -22,15 +22,15 @@ sub pi_fork_exec ($$$$$$$) {
                 $pid = -1;
         }
         if ($pid == 0) {
+                $SIG{__DIE__} = sub { warn @_; _exit 1 };
                 for my $child_fd (0..$#$redir) {
                         my $parent_fd = $redir->[$child_fd];
                         next if $parent_fd == $child_fd;
                         dup2($parent_fd, $child_fd) or
-                                die "dup2($parent_fd, $child_fd): $!\n";
+                                die "dup2($parent_fd, $child_fd): $!";
                 }
                 if ($pgid >= 0 && !defined(setpgid(0, $pgid))) {
-                        warn "setpgid: $!";
-                        _exit(1);
+                        die "setpgid(0, $pgid): $!";
                 }
                 $SIG{$_} = 'DEFAULT' for keys %SIG;
                 if ($cd ne '') {
@@ -39,20 +39,18 @@ sub pi_fork_exec ($$$$$$$) {
                 while (@$rlim) {
                         my ($r, $soft, $hard) = splice(@$rlim, 0, 3);
                         BSD::Resource::setrlimit($r, $soft, $hard) or
-                          warn "failed to set $r=[$soft,$hard]\n";
+                                die "setrlimit($r=[$soft,$hard]: $!)";
                 }
                 $old->delset(POSIX::SIGCHLD) or die "delset SIGCHLD: $!";
                 sigprocmask(SIG_SETMASK, $old) or die "SETMASK: ~SIGCHLD: $!";
+                $cmd->[0] = $f;
                 if ($ENV{MOD_PERL}) {
-                        exec which('env'), '-i', @$env, @$cmd;
-                        die "exec env -i ... $cmd->[0] failed: $!\n";
+                        @$cmd = (which('env'), '-i', @$env, @$cmd);
                 } else {
-                        local %ENV = map { split(/=/, $_, 2) } @$env;
-                        my @cmd = @$cmd;
-                        $cmd[0] = $f;
-                        exec @cmd;
-                        die "exec $cmd->[0] failed: $!\n";
+                        %ENV = map { split(/=/, $_, 2) } @$env;
                 }
+                exec @$cmd;
+                die "exec @$cmd failed: $!";
         }
         sigprocmask(SIG_SETMASK, $old) or die "can't unblock signals: $!";
         $! = $syserr;