From cf731a1422064344f25c214670fb0007ab1d4c2c Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 17 Dec 2020 11:23:57 +0000 Subject: [PATCH] lei: restore default __DIE__ handler for event loop The kqueue code paths will trigger exceptions which are caught by eval{}, so we can't be calling exit() from the __DIE__ handler and expect eval to catch it. We only need the __DIE__ handler to deal with fork or open failures at startup (since stderr is pointed to /dev/null). After that we can rely on OnDestroy writing errors to syslog when it goes out of scope. --- lib/PublicInbox/LEI.pm | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index 5399fade..95b48095 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -20,6 +20,7 @@ use PublicInbox::Syscall qw($SFD_NONBLOCK EPOLLIN EPOLLONESHOT); use PublicInbox::Sigfd; use PublicInbox::DS qw(now); use PublicInbox::Spawn qw(spawn); +use PublicInbox::OnDestroy; use Text::Wrap qw(wrap); use File::Path qw(mkpath); use File::Spec; @@ -386,7 +387,6 @@ sub optparse ($$$) { sub dispatch { my ($self, $cmd, @argv) = @_; local $SIG{__WARN__} = sub { err($self, "@_") }; - local $SIG{__DIE__} = 'DEFAULT'; return _help($self, 'no command given') unless defined($cmd); my $func = "lei_$cmd"; $func =~ tr/-/_/; @@ -602,12 +602,12 @@ sub lazy_start { my $oldset = PublicInbox::Sigfd::block_signals(); my $pid = fork // die "fork: $!"; return if $pid; + require PublicInbox::Listener; + require PublicInbox::EOFpipe; openlog($path, 'pid', 'user'); local $SIG{__DIE__} = sub { syslog('crit', "@_"); - exit $! if $!; - exit $? >> 8 if $? >> 8; - exit 255; + die; # calls the default __DIE__ handler }; local $SIG{__WARN__} = sub { syslog('warning', "@_") }; open(STDIN, '+<', '/dev/null') or die "redirect stdin failed: $!\n"; @@ -616,10 +616,13 @@ sub lazy_start { setsid(); $pid = fork // die "fork: $!"; return if $pid; + $SIG{__DIE__} = 'DEFAULT'; + my $on_destroy = PublicInbox::OnDestroy->new(sub { + my ($owner_pid) = @_; + syslog('crit', "$@") if $@ && $$ == $owner_pid; + }, $$); $0 = "lei-daemon $path"; local %PATH2CFG; - require PublicInbox::Listener; - require PublicInbox::EOFpipe; $l->blocking(0); $eof_w->blocking(0); $eof_r->blocking(0); @@ -680,6 +683,7 @@ sub lazy_start { $n; # true: continue, false: stop }); PublicInbox::DS->EventLoop; + $@ = undef if $on_destroy; # quiet OnDestroy if we got here exit($exit_code // 0); } -- 2.50.0