X-Git-Url: http://git.archive.openwrt.org/?p=project%2Flibubox.git;a=blobdiff_plain;f=uloop.c;h=9ebeca6791b97e313d8b3c82081c778f63fbe056;hp=ee568a8cb7f7b7ed4042f10db8fc66c68267d898;hb=827ad8337e88ec9e0bf73a8af1d6cf8555e8ef3d;hpb=73a88451ddcc58ba1217dea22fee3eb5b20cf79b diff --git a/uloop.c b/uloop.c index ee568a8..9ebeca6 100644 --- a/uloop.c +++ b/uloop.c @@ -58,7 +58,6 @@ static struct list_head processes = LIST_HEAD_INIT(processes); static int poll_fd = -1; bool uloop_cancelled = false; -bool uloop_handle_sigchld = true; static bool do_sigchld = false; static struct uloop_fd_event cur_fds[ULOOP_MAX_EVENTS]; @@ -454,14 +453,14 @@ int uloop_timeout_set(struct uloop_timeout *timeout, int msecs) if (timeout->pending) uloop_timeout_cancel(timeout); - uloop_gettime(&timeout->time); + uloop_gettime(time); time->tv_sec += msecs / 1000; time->tv_usec += (msecs % 1000) * 1000; if (time->tv_usec > 1000000) { time->tv_sec++; - time->tv_usec %= 1000000; + time->tv_usec -= 1000000; } return uloop_timeout_add(timeout); @@ -559,31 +558,61 @@ static void uloop_sigchld(int signo) do_sigchld = true; } -static void uloop_setup_signals(bool add) +static void uloop_install_handler(int signum, void (*handler)(int), struct sigaction* old, bool add) { - static struct sigaction old_sigint, old_sigchld; struct sigaction s; + struct sigaction *act; - memset(&s, 0, sizeof(struct sigaction)); + act = NULL; + sigaction(signum, NULL, &s); if (add) { - s.sa_handler = uloop_handle_sigint; - s.sa_flags = 0; + if (s.sa_handler == SIG_DFL) { /* Do not override existing custom signal handlers */ + memcpy(old, &s, sizeof(struct sigaction)); + s.sa_handler = handler; + s.sa_flags = 0; + act = &s; + } + } + else if (s.sa_handler == handler) { /* Do not restore if someone modified our handler */ + act = old; + } + + if (act != NULL) + sigaction(signum, act, NULL); +} + +static void uloop_ignore_signal(int signum, bool ignore) +{ + struct sigaction s; + void *new_handler = NULL; + + sigaction(signum, NULL, &s); + + if (ignore) { + if (s.sa_handler == SIG_DFL) /* Ignore only if there isn't any custom handler */ + new_handler = SIG_IGN; } else { - s = old_sigint; + if (s.sa_handler == SIG_IGN) /* Restore only if noone modified our SIG_IGN */ + new_handler = SIG_DFL; } - sigaction(SIGINT, &s, &old_sigint); + if (new_handler) { + s.sa_handler = new_handler; + s.sa_flags = 0; + sigaction(signum, &s, NULL); + } +} - if (!uloop_handle_sigchld) - return; +static void uloop_setup_signals(bool add) +{ + static struct sigaction old_sigint, old_sigchld, old_sigterm; - if (add) - s.sa_handler = uloop_sigchld; - else - s = old_sigchld; + uloop_install_handler(SIGINT, uloop_handle_sigint, &old_sigint, add); + uloop_install_handler(SIGTERM, uloop_handle_sigint, &old_sigterm, add); + uloop_install_handler(SIGCHLD, uloop_sigchld, &old_sigchld, add); - sigaction(SIGCHLD, &s, &old_sigchld); + uloop_ignore_signal(SIGPIPE, add); } static int uloop_get_next_timeout(struct timeval *tv) @@ -646,6 +675,7 @@ void uloop_run(void) if (!recursive_calls++) uloop_setup_signals(true); + uloop_cancelled = false; while(!uloop_cancelled) { uloop_gettime(&tv);