rktio: always set signal mask to empty after fork
Saving and restoring the signal-mask state does not work right, since rktio itself may block SIGCHLD in some cases, and it doesn't seem useful/right to preserve the mask after fork.
This commit is contained in:
parent
6cfc7b880b
commit
4c836a1dd1
|
@ -595,7 +595,10 @@
|
||||||
exe
|
exe
|
||||||
(path->complete-path "unix_check.c" (or (current-load-relative-directory)
|
(path->complete-path "unix_check.c" (or (current-load-relative-directory)
|
||||||
(current-directory)))))
|
(current-directory)))))
|
||||||
(test #t 'subprocess-state (system* exe)))
|
(test #t 'subprocess-state (let ([o (open-output-bytes)])
|
||||||
|
(or (parameterize ([current-output-port o])
|
||||||
|
(system* exe))
|
||||||
|
(get-output-bytes o)))))
|
||||||
(delete-directory/files dir)))
|
(delete-directory/files dir)))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/* Make sure a child process is started with normal properties, such
|
/* Make sure a child process is started with normal properties, such
|
||||||
as no blocked signals */
|
as no blocked signals */
|
||||||
|
@ -11,10 +12,12 @@ int main()
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* SIGPROF tends to be near the end of the range of signal IDs */
|
/* SIGPROF tends to be near the end of the range of signal IDs */
|
||||||
for (i = 1; i < SIGPROF; i++) {
|
for (i = 1; i <= SIGPROF; i++) {
|
||||||
if (sigaction(i, NULL, &sa) == 0) {
|
if (sigaction(i, NULL, &sa) == 0) {
|
||||||
if (sa.sa_handler != SIG_DFL)
|
if (sa.sa_handler != SIG_DFL) {
|
||||||
|
printf("handler %d: %p\n", i, (void *)sa.sa_handler);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* sigaction sometimes isn't allowed at all on SIGKILL,
|
/* sigaction sometimes isn't allowed at all on SIGKILL,
|
||||||
for example, so ignore that failure */
|
for example, so ignore that failure */
|
||||||
|
@ -24,8 +27,22 @@ int main()
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
sigprocmask(SIG_BLOCK, &set, &old_set);
|
sigprocmask(SIG_BLOCK, &set, &old_set);
|
||||||
|
|
||||||
return (sigismember(&old_set, SIGCHLD)
|
if (sigismember(&old_set, SIGCHLD)) {
|
||||||
|| sigismember(&old_set, SIGINT)
|
printf("masked: SIGCHLD\n");
|
||||||
|| sigismember(&old_set, SIGHUP)
|
return 1;
|
||||||
|| sigismember(&old_set, SIGQUIT));
|
}
|
||||||
|
if (sigismember(&old_set, SIGINT)) {
|
||||||
|
printf("masked: SIGINT\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (sigismember(&old_set, SIGHUP)) {
|
||||||
|
printf("masked: SIGHUP\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (sigismember(&old_set, SIGQUIT)) {
|
||||||
|
printf("masked: SIGQUIT\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1004,7 +1004,9 @@ RKTIO_EXTERN void rktio_install_os_signal_handler(rktio_t *rktio);
|
||||||
Ctl-C on Windows) to signal the handle of `rktio` and also records
|
Ctl-C on Windows) to signal the handle of `rktio` and also records
|
||||||
the signal for reporting via `rktio_poll_os_signal`. Only one
|
the signal for reporting via `rktio_poll_os_signal`. Only one
|
||||||
`rktio` can be registered this way at a time. This function must
|
`rktio` can be registered this way at a time. This function must
|
||||||
not be called in two threads at the same time. */
|
not be called in two threads at the same time; more generally, it
|
||||||
|
can only be called when `rktio_will_modify_os_signal_handler`
|
||||||
|
can be called for SIGINT, etc. */
|
||||||
|
|
||||||
RKTIO_EXTERN_NOERR int rktio_poll_os_signal(rktio_t *rktio);
|
RKTIO_EXTERN_NOERR int rktio_poll_os_signal(rktio_t *rktio);
|
||||||
/* Returns one of the following, not counting the last one: */
|
/* Returns one of the following, not counting the last one: */
|
||||||
|
@ -1021,11 +1023,11 @@ RKTIO_EXTERN void rktio_will_modify_os_signal_handler(int sig_id);
|
||||||
about to be modified within the process but outside of rktio, where
|
about to be modified within the process but outside of rktio, where
|
||||||
`sig_id` is a signal identifier --- such as SIGINT or SIGTERM. This
|
`sig_id` is a signal identifier --- such as SIGINT or SIGTERM. This
|
||||||
notification allows rktio to record the current signal disposition
|
notification allows rktio to record the current signal disposition
|
||||||
so that it can be restored after forking a new Unix process.
|
so that it can be restored after forking a new Unix process. Signal
|
||||||
Signal registrations should happen only before multiple threads use
|
registrations should happen only before multiple threads use rktio,
|
||||||
rktio, and registration of the signal can happen before any
|
and registration of the signal can happen before any `rktio_init`
|
||||||
`rktio_init` call. On the first `rktio_will_modify_os_signal_handler`
|
call. After a signal is registered, trying to re-register it after
|
||||||
call, the signal mask is also recorded to be restored in a fork. */
|
threads start is harmless. */
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* Time and date */
|
/* Time and date */
|
||||||
|
|
|
@ -982,6 +982,10 @@ int rktio_process_init(rktio_t *rktio)
|
||||||
it's a per-thread setting on Linux, and we want SIGCHLD blocked everywhere. */
|
it's a per-thread setting on Linux, and we want SIGCHLD blocked everywhere. */
|
||||||
block_sigchld();
|
block_sigchld();
|
||||||
|
|
||||||
|
/* We'll set a handler later (possibly after other threads start),
|
||||||
|
so register SIGCHLD now: */
|
||||||
|
rktio_will_modify_os_signal_handler(SIGCHLD);
|
||||||
|
|
||||||
centralized_start_child_signal_handler();
|
centralized_start_child_signal_handler();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -127,18 +127,10 @@ typedef struct signal_handler_saved_disposition {
|
||||||
} signal_handler_saved_disposition;
|
} signal_handler_saved_disposition;
|
||||||
|
|
||||||
static signal_handler_saved_disposition *saved_dispositions;
|
static signal_handler_saved_disposition *saved_dispositions;
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
|
||||||
static sigset_t initial_procmask;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void rktio_will_modify_os_signal_handler(int sig_id) {
|
void rktio_will_modify_os_signal_handler(int sig_id) {
|
||||||
signal_handler_saved_disposition *saved;
|
signal_handler_saved_disposition *saved;
|
||||||
|
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
|
||||||
if (saved_dispositions == NULL)
|
|
||||||
sigprocmask(SIG_SETMASK, NULL, &initial_procmask);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (saved = saved_dispositions; saved; saved = saved->next)
|
for (saved = saved_dispositions; saved; saved = saved->next)
|
||||||
if (saved->sig_id == sig_id)
|
if (saved->sig_id == sig_id)
|
||||||
return;
|
return;
|
||||||
|
@ -156,13 +148,13 @@ void rktio_will_modify_os_signal_handler(int sig_id) {
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
/* called in a child thread after `fork */
|
/* called in a child thread after `fork */
|
||||||
void rktio_restore_modified_signal_handlers() {
|
void rktio_restore_modified_signal_handlers() {
|
||||||
if (saved_dispositions) {
|
|
||||||
signal_handler_saved_disposition *saved;
|
signal_handler_saved_disposition *saved;
|
||||||
|
sigset_t set;
|
||||||
|
|
||||||
for (saved = saved_dispositions; saved; saved = saved->next)
|
for (saved = saved_dispositions; saved; saved = saved->next)
|
||||||
sigaction(saved->sig_id, &saved->sa, NULL);
|
sigaction(saved->sig_id, &saved->sa, NULL);
|
||||||
|
|
||||||
sigprocmask(SIG_SETMASK, &initial_procmask, NULL);
|
sigemptyset(&set);
|
||||||
}
|
sigprocmask(SIG_SETMASK, &set, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user