When built with an old thread implementation (or for a sparc target), the implementation of the system() function doesn't conform to its specification. Namely, it resets the SIGCHLD handler to its default instead of blocking the signal, which may result in "lost" signals if a custom handler was installed. Replace this by appropriate calls to sigprocmask().
Signed-off-by: Richard Braun <rbr...@sceen.net> --- libc/stdlib/system.c | 22 +++++++++++++++++----- 1 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libc/stdlib/system.c b/libc/stdlib/system.c index a0ff726..4ed6618 100644 --- a/libc/stdlib/system.c +++ b/libc/stdlib/system.c @@ -33,25 +33,34 @@ extern __typeof(system) __libc_system; int __libc_system(const char *command) { int wait_val, pid; - __sighandler_t save_quit, save_int, save_chld; + __sighandler_t save_quit, save_int; + sigset_t smask, omask; if (command == 0) return 1; save_quit = signal(SIGQUIT, SIG_IGN); save_int = signal(SIGINT, SIG_IGN); - save_chld = signal(SIGCHLD, SIG_DFL); + + sigemptyset(&smask); + sigaddset(&smask, SIGCHLD); + + if (sigprocmask(SIG_BLOCK, &smask, &omask) != 0) { + signal(SIGQUIT, save_quit); + signal(SIGINT, save_int); + return -1; + } if ((pid = vfork()) < 0) { signal(SIGQUIT, save_quit); signal(SIGINT, save_int); - signal(SIGCHLD, save_chld); + sigprocmask(SIG_SETMASK, &omask, NULL); return -1; } if (pid == 0) { signal(SIGQUIT, SIG_DFL); signal(SIGINT, SIG_DFL); - signal(SIGCHLD, SIG_DFL); + sigprocmask(SIG_SETMASK, &omask, NULL); execl("/bin/sh", "sh", "-c", command, (char *) 0); _exit(127); @@ -69,7 +78,10 @@ int __libc_system(const char *command) signal(SIGQUIT, save_quit); signal(SIGINT, save_int); - signal(SIGCHLD, save_chld); + + if (sigprocmask(SIG_SETMASK, &omask, NULL) != 0) + wait_val = -1; + return wait_val; } #else -- 1.7.2.5 _______________________________________________ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc