]> Sergey Matveev's repositories - public-inbox.git/commitdiff
spawn_pp: die more consistently in child
authorEric Wong <e@80x24.org>
Sun, 7 Feb 2021 08:51:46 +0000 (08:51 +0000)
committerEric Wong <e@80x24.org>
Sun, 7 Feb 2021 22:56:56 +0000 (22:56 +0000)
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.

lib/PublicInbox/SpawnPP.pm

index 401cb78de083ebf294ddec7847294d849d1c1142..2c5edef62efc55acbf48e2e0f4cc6efa6ac852d2 100644 (file)
@@ -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;