diff options
author | Eric Wong <e@80x24.org> | 2021-02-07 08:51:43 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2021-02-07 22:56:52 +0000 |
commit | 975dffc9bcb96f10bdc8a70bf6af67c2b46ab4b5 (patch) | |
tree | 1161b13fda37a034bbd570296b7e13a12a2dd60f /lib/PublicInbox/Spawn.pm | |
parent | 17b960feb2362af29848cdac7548197bcccb3ff7 (diff) | |
download | public-inbox-975dffc9bcb96f10bdc8a70bf6af67c2b46ab4b5.tar.gz |
We continue to unblock SIGCHLD unconditionally, but also any signals not blocked by the parent (wq_worker). This will allow Ctrl-C (SIGINT) to stop "git clone" and allow git-clone cleanup to be performed and other long-running processes when pi_fork_exec supports setpgid(2). This won't affect existing daemons on systems with signalfd(2) or EVFILT_SIGNAL at all, since those run with signals blocked anyways.
Diffstat (limited to 'lib/PublicInbox/Spawn.pm')
-rw-r--r-- | lib/PublicInbox/Spawn.pm | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/lib/PublicInbox/Spawn.pm b/lib/PublicInbox/Spawn.pm index f7dcb024..bac24dd1 100644 --- a/lib/PublicInbox/Spawn.pm +++ b/lib/PublicInbox/Spawn.pm @@ -82,20 +82,20 @@ int pi_fork_exec(SV *redirref, SV *file, SV *cmdref, SV *envref, SV *rlimref, const char *filename = SvPV_nolen(file); pid_t pid; char **argv, **envp; - sigset_t set, old, cset; + sigset_t set, old; int ret, perrnum, cerrnum = 0; + int chld_is_member; AV2C_COPY(argv, cmd); AV2C_COPY(envp, env); - ret = sigfillset(&set); - assert(ret == 0 && "BUG calling sigfillset"); - ret = sigprocmask(SIG_SETMASK, &set, &old); - assert(ret == 0 && "BUG calling sigprocmask to block"); - ret = sigemptyset(&cset); - assert(ret == 0 && "BUG calling sigemptyset"); - ret = sigaddset(&cset, SIGCHLD); - assert(ret == 0 && "BUG calling sigaddset for SIGCHLD"); + if (sigfillset(&set)) return -1; + if (sigprocmask(SIG_SETMASK, &set, &old)) return -1; + chld_is_member = sigismember(&old, SIGCHLD); + if (chld_is_member < 0) return -1; + if (chld_is_member > 0) + sigdelset(&old, SIGCHLD); + pid = vfork(); if (pid == 0) { int sig; @@ -127,15 +127,13 @@ int pi_fork_exec(SV *redirref, SV *file, SV *cmdref, SV *envref, SV *rlimref, exit_err(&cerrnum); } - /* - * don't bother unblocking other signals for now, just SIGCHLD. - * we don't want signals to the group taking out a subprocess - */ - (void)sigprocmask(SIG_UNBLOCK, &cset, NULL); + (void)sigprocmask(SIG_SETMASK, &old, NULL); execve(filename, argv, envp); exit_err(&cerrnum); } perrnum = errno; + if (chld_is_member > 0) + sigaddset(&old, SIGCHLD); ret = sigprocmask(SIG_SETMASK, &old, NULL); assert(ret == 0 && "BUG calling sigprocmask to restore"); if (cerrnum) { |