X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=uloop.c;h=ee568a8cb7f7b7ed4042f10db8fc66c68267d898;hb=178fe974af1d0fa4130f865f7b494b0d6b1b05a4;hp=9a0590f47547604802867a074443fb8f37b64a59;hpb=04f194aa8a04926fe7f2e42bbf9ba6c62d49339e;p=project%2Flibubox.git diff --git a/uloop.c b/uloop.c index 9a0590f..ee568a8 100644 --- a/uloop.c +++ b/uloop.c @@ -174,7 +174,8 @@ static int uloop_fetch_events(int timeout) if (events[n].flags & EV_ERROR) { u->error = true; - uloop_fd_delete(u); + if (!(u->flags & ULOOP_ERROR_CB)) + uloop_fd_delete(u); } if(events[n].filter == EVFILT_READ) @@ -268,7 +269,8 @@ static int uloop_fetch_events(int timeout) if (events[n].events & (EPOLLERR|EPOLLHUP)) { u->error = true; - uloop_fd_delete(u); + if (!(u->flags & ULOOP_ERROR_CB)) + uloop_fd_delete(u); } if(!(events[n].events & (EPOLLRDHUP|EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP))) { @@ -383,6 +385,7 @@ int uloop_fd_add(struct uloop_fd *sock, unsigned int flags) sock->registered = true; sock->eof = false; + sock->error = false; out: return ret; @@ -556,19 +559,31 @@ static void uloop_sigchld(int signo) do_sigchld = true; } -static void uloop_setup_signals(void) +static void uloop_setup_signals(bool add) { + static struct sigaction old_sigint, old_sigchld; struct sigaction s; memset(&s, 0, sizeof(struct sigaction)); - s.sa_handler = uloop_handle_sigint; - s.sa_flags = 0; - sigaction(SIGINT, &s, NULL); - if (uloop_handle_sigchld) { - s.sa_handler = uloop_sigchld; - sigaction(SIGCHLD, &s, NULL); + if (add) { + s.sa_handler = uloop_handle_sigint; + s.sa_flags = 0; + } else { + s = old_sigint; } + + sigaction(SIGINT, &s, &old_sigint); + + if (!uloop_handle_sigchld) + return; + + if (add) + s.sa_handler = uloop_sigchld; + else + s = old_sigchld; + + sigaction(SIGCHLD, &s, &old_sigchld); } static int uloop_get_next_timeout(struct timeval *tv) @@ -621,9 +636,16 @@ static void uloop_clear_processes(void) void uloop_run(void) { + static int recursive_calls = 0; struct timeval tv; - uloop_setup_signals(); + /* + * Handlers are only updated for the first call to uloop_run() (and restored + * when this call is done). + */ + if (!recursive_calls++) + uloop_setup_signals(true); + while(!uloop_cancelled) { uloop_gettime(&tv); @@ -636,6 +658,9 @@ void uloop_run(void) uloop_gettime(&tv); uloop_run_events(uloop_get_next_timeout(&tv)); } + + if (!--recursive_calls) + uloop_setup_signals(false); } void uloop_done(void)