Hi, Given the following C program: --8<---------------cut here---------------start------------->8--- #include <stdio.h> #include <signal.h>
int main(void) { struct sigaction act; sigaction(SIGINT, NULL, &act); printf("%p %p %p\n", act.sa_handler, SIG_IGN, SIG_DFL); } --8<---------------cut here---------------end--------------->8--- and its ouput from various executions: 1) $ ./a.out => (nil) 0x1 (nil) 2) $ guile -c '(system "./a.out")' => (nil) 0x1 (nil) 3) $ guile -c '(system* "./a.out")' => 0x1 0x1 (nil) We can see that 3) does not honor restoration of `SIGINT' to `SIG_DFL' like `system(3)' does. This seems to be because of the following sigaction before the creation of the process: --8<---------------cut here---------------start------------->8--- 1697 scm_dynwind_sigaction (SIGINT, 1698 scm_from_uintptr_t ((uintptr_t) SIG_IGN), 1699 SCM_UNDEFINED); 1700 #ifdef SIGQUIT 1701 scm_dynwind_sigaction (SIGQUIT, 1702 scm_from_uintptr_t ((uintptr_t) SIG_IGN), 1703 SCM_UNDEFINED); 1704 #endif 1705 1706 err = piped_process (&pid, prog, args, 1707 SCM_UNDEFINED, SCM_UNDEFINED); --8<---------------cut here---------------end--------------->8--- >From execve(2): POSIX.1 specifies that the dispositions of any signals that are ignored or set to the default are left unchanged. POSIX.1 specifies one exception: if SIGCHLD is being ignored, then an implementation may leave the disposition unchanged or reset it to the default; Linux does the former. Therefore, setting `SIG_IGN' for `SIGINT' before the fork/execve results in ignoring the signals in the child, which is unexpected as a user of `system(3)'. The solution would be to restore `SIG_DFL' before `execve(2)' if before the call to `system*' the action was not `SIG_IGN'. In the mean time, I have a solution that works for single-threaded application: --8<---------------cut here---------------start------------->8--- (define (system* . args) (let ((handler+flags (sigaction SIGINT))) (dynamic-wind (lambda () (sigaction SIGINT SIG_IGN)) (lambda () (let ((cpid (primitive-fork))) (if (zero? cpid) (catch #t (lambda () (sigaction SIGINT SIG_DFL) (apply execlp (car args) args)) (lambda _ (primitive-exit EXIT_FAILURE))) (waitpid cpid)))) (lambda () (sigaction SIGINT (car handler+flags) (cdr handler+flags)))))) --8<---------------cut here---------------end--------------->8--- Thanks, Olivier -- Olivier Dion oldiob.ca