From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-3.9 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id D918F1F8C8 for ; Sun, 7 Feb 2021 08:52:01 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 04/19] spawn_pp: die more consistently in child Date: Sun, 7 Feb 2021 08:51:46 +0000 Message-Id: <20210207085201.13871-5-e@80x24.org> In-Reply-To: <20210207085201.13871-1-e@80x24.org> References: <20210207085201.13871-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: 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 | 20 +++++++++----------- 1 file 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;