diff options
author | Eric Wong <e@80x24.org> | 2019-11-24 00:22:28 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2019-11-24 21:35:16 +0000 |
commit | 81a9a43fb858d197ffd1532d73f9f22739f940ff (patch) | |
tree | c83f6cde682c953d512eb2b84034a4fa0a2a8b42 | |
parent | 11eddc4ddbffc6fee5f329735c47f1558e6a40c6 (diff) | |
download | public-inbox-81a9a43fb858d197ffd1532d73f9f22739f940ff.tar.gz |
`$SIG{FOO} = "IGNORE"' will cause the daemon to miss signals entirely. Instead, we can use sigprocmask to block signal delivery until we have our signal handlers setup. This closes a race where a PID file can be written for an init script and a signal to be dropped via "IGNORE".
-rw-r--r-- | lib/PublicInbox/Daemon.pm | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/lib/PublicInbox/Daemon.pm b/lib/PublicInbox/Daemon.pm index b3743f5c..e830a98f 100644 --- a/lib/PublicInbox/Daemon.pm +++ b/lib/PublicInbox/Daemon.pm @@ -8,7 +8,7 @@ use warnings; use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/; use IO::Handle; use IO::Socket; -use POSIX qw(WNOHANG); +use POSIX qw(WNOHANG :signal_h); use Socket qw(IPPROTO_TCP SOL_SOCKET); sub SO_ACCEPTFILTER () { 0x1000 } use Cwd qw/abs_path/; @@ -19,7 +19,7 @@ require PublicInbox::EvCleanup; require PublicInbox::Listener; require PublicInbox::ParentPipe; my @CMD; -my $set_user; +my ($set_user, $oldset); my (@cfg_listen, $stdout, $stderr, $group, $user, $pid_file, $daemonize); my $worker_processes = 1; my @listeners; @@ -76,9 +76,11 @@ sub accept_tls_opt ($) { sub daemon_prepare ($) { my ($default_listen) = @_; + $oldset = POSIX::SigSet->new(); + my $newset = POSIX::SigSet->new(); + $newset->fillset or die "fillset: $!"; + sigprocmask(SIG_SETMASK, $newset, $oldset) or die "sigprocmask: $!"; @CMD = ($0, @ARGV); - $SIG{HUP} = $SIG{USR1} = $SIG{USR2} = $SIG{PIPE} = - $SIG{TTIN} = $SIG{TTOU} = $SIG{WINCH} = 'IGNORE'; my %opts = ( 'l|listen=s' => \@cfg_listen, '1|stdout=s' => \$stdout, @@ -482,6 +484,7 @@ sub master_loop { syswrite($w, '.'); }; } + sigprocmask(SIG_SETMASK, $oldset) or die "sigprocmask: $!"; reopen_logs(); # main loop my $quit = 0; @@ -616,6 +619,7 @@ sub daemon_loop ($$$$) { # this calls epoll_create: PublicInbox::Listener->new($_, $tls_cb || $post_accept) } @listeners; + sigprocmask(SIG_SETMASK, $oldset) or die "sigprocmask: $!"; PublicInbox::DS->EventLoop; $parent_pipe = undef; } |