diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2009-08-28 12:04:22 +0930 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-08-28 14:03:41 +1000 |
commit | 6abb637e3e0d23635fdbbb91c163731b325d696d (patch) | |
tree | 0cf9548dbed2a26f7f4a395b243e6f359de4d49b | |
parent | 398d0c2929026fccb3409316720a4dcad225ab05 (diff) | |
download | samba-6abb637e3e0d23635fdbbb91c163731b325d696d.tar.gz samba-6abb637e3e0d23635fdbbb91c163731b325d696d.tar.bz2 samba-6abb637e3e0d23635fdbbb91c163731b325d696d.zip |
lib/tevent: fix race with signals and tevent_common_add_signal
We carefully preserve the old signal handler, but we replace it before
we've set up everything; in particular, if we fail setting up the
pipe_hack we could write a NUL char to stdout (fd 0), instead of
calling the old signal handler.
Replace the signal handler as the very last thing we do.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r-- | lib/tevent/tevent_signal.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c index 429995318b..5e4e81b73c 100644 --- a/lib/tevent/tevent_signal.c +++ b/lib/tevent/tevent_signal.c @@ -219,6 +219,26 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, return NULL; } + /* we need to setup the pipe hack handler if not already + setup */ + if (ev->pipe_fde == NULL) { + if (sig_state->pipe_hack[0] == 0 && + sig_state->pipe_hack[1] == 0) { + if (pipe(sig_state->pipe_hack) == -1) { + talloc_free(se); + return NULL; + } + ev_set_blocking(sig_state->pipe_hack[0], false); + ev_set_blocking(sig_state->pipe_hack[1], false); + } + ev->pipe_fde = tevent_add_fd(ev, ev, sig_state->pipe_hack[0], + TEVENT_FD_READ, signal_pipe_handler, NULL); + if (!ev->pipe_fde) { + talloc_free(se); + return NULL; + } + } + /* only install a signal handler if not already installed */ if (sig_state->sig_handlers[signum] == NULL) { struct sigaction act; @@ -255,26 +275,6 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, talloc_set_destructor(se, tevent_signal_destructor); talloc_set_destructor(sl, tevent_common_signal_list_destructor); - /* we need to setup the pipe hack handler if not already - setup */ - if (ev->pipe_fde == NULL) { - if (sig_state->pipe_hack[0] == 0 && - sig_state->pipe_hack[1] == 0) { - if (pipe(sig_state->pipe_hack) == -1) { - talloc_free(se); - return NULL; - } - ev_set_blocking(sig_state->pipe_hack[0], false); - ev_set_blocking(sig_state->pipe_hack[1], false); - } - ev->pipe_fde = tevent_add_fd(ev, ev, sig_state->pipe_hack[0], - TEVENT_FD_READ, signal_pipe_handler, NULL); - if (!ev->pipe_fde) { - talloc_free(se); - return NULL; - } - } - return se; } |