Skip to content

Commit 80c03b4

Browse files
committed
subprocess: unblock/reset signals before running child process
During execve() ignored and blocked signals carry over to the child process, though apparently for SIGCHLD (which the bug report was about) this is implementation-defined. fixes #9613
1 parent e7fbc86 commit 80c03b4

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

osdep/subprocess-posix.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@
3333

3434
extern char **environ;
3535

36+
#ifdef SIGRTMAX
37+
#define SIGNAL_MAX SIGRTMAX
38+
#else
39+
#define SIGNAL_MAX 32
40+
#endif
41+
3642
#define SAFE_CLOSE(fd) do { if ((fd) >= 0) close((fd)); (fd) = -1; } while (0)
3743

3844
// Async-signal-safe execvpe(). POSIX does not list it as async-signal-safe
@@ -65,6 +71,20 @@ static int as_execvpe(const char *path, const char *file, char *const argv[],
6571
return -1;
6672
}
6773

74+
// In the child process, resets the signal mask to defaults. Also clears any
75+
// signal handlers first so nothing funny happens.
76+
static void reset_signals_child(void)
77+
{
78+
struct sigaction sa = { 0 };
79+
sigset_t sigmask;
80+
sa.sa_handler = SIG_DFL;
81+
sigemptyset(&sigmask);
82+
83+
for (int nr = 1; nr < SIGNAL_MAX; nr++)
84+
sigaction(nr, &sa, NULL);
85+
sigprocmask(SIG_SETMASK, &sigmask, NULL);
86+
}
87+
6888
// Returns 0 on any error, valid PID on success.
6989
// This function must be async-signal-safe, as it may be called from a fork().
7090
static pid_t spawn_process(const char *path, struct mp_subprocess_opts *opts,
@@ -96,6 +116,7 @@ static pid_t spawn_process(const char *path, struct mp_subprocess_opts *opts,
96116
}
97117
if (fres == 0) {
98118
// child
119+
reset_signals_child();
99120

100121
for (int n = 0; n < opts->num_fds; n++) {
101122
if (src_fds[n] == opts->fds[n].fd) {

0 commit comments

Comments
 (0)