Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6226:315b954801f7 HEAD
waitpid() ntlm_auth workers so they won't be left as zombies.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 07 Aug 2007 14:45:50 +0300 |
parents | 336ad0e3c78f |
children | b1cfce4263a2 |
files | src/auth/mech-winbind.c |
diffstat | 1 files changed, 48 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/mech-winbind.c Tue Aug 07 14:38:13 2007 +0300 +++ b/src/auth/mech-winbind.c Tue Aug 07 14:45:50 2007 +0300 @@ -8,6 +8,7 @@ */ #include "common.h" +#include "lib-signals.h" #include "mech.h" #include "str.h" #include "buffer.h" @@ -17,6 +18,7 @@ #include <stdlib.h> #include <unistd.h> +#include <sys/wait.h> #define DEFAULT_WINBIND_HELPER_PATH "/usr/bin/ntlm_auth" @@ -28,6 +30,8 @@ struct winbind_helper { const char *param; + pid_t pid; + struct istream *in_pipe; struct ostream *out_pipe; }; @@ -40,12 +44,14 @@ }; static struct winbind_helper winbind_ntlm_context = { - "--helper-protocol=squid-2.5-ntlmssp", NULL, NULL + "--helper-protocol=squid-2.5-ntlmssp", -1, NULL, NULL }; static struct winbind_helper winbind_spnego_context = { - "--helper-protocol=gss-spnego", NULL, NULL + "--helper-protocol=gss-spnego", -1, NULL, NULL }; +static bool sigchld_handler_set = FALSE; + static void winbind_helper_disconnect(struct winbind_helper *winbind) { if (winbind->in_pipe != NULL) @@ -54,12 +60,46 @@ o_stream_destroy(&winbind->out_pipe); } +static void winbind_wait_pid(struct winbind_helper *winbind) +{ + int status; + + if (winbind->pid == -1) + return; + + /* FIXME: if we ever do some other kind of forking, this needs fixing */ + if (waitpid(winbind->pid, &status, WNOHANG) == -1) { + if (errno != ECHILD && errno != EINTR) + i_error("waitpid() failed: %m"); + return; + } + + if (WIFSIGNALED(status)) { + i_error("winbind: ntlm_auth died with signal %d", + WTERMSIG(status)); + } else if (WIFEXITED(status)) { + i_error("winbind: ntlm_auth exited with exit code %d", + WEXITSTATUS(status)); + } else { + /* shouldn't happen */ + i_error("winbind: ntlm_auth exited with status %d", + status); + } +} + +static void sigchld_handler(int signo __attr_unused__, + void *context __attr_unused__) +{ + winbind_wait_pid(&winbind_ntlm_context); + winbind_wait_pid(&winbind_spnego_context); +} + static void winbind_helper_connect(struct winbind_helper *winbind) { int infd[2], outfd[2]; pid_t pid; - if (winbind->in_pipe != NULL) + if (winbind->in_pipe != NULL || winbind->pid != -1) return; if (pipe(infd) < 0) { @@ -109,6 +149,11 @@ i_stream_create_fd(infd[0], AUTH_CLIENT_MAX_LINE_LENGTH, TRUE); winbind->out_pipe = o_stream_create_fd(outfd[1], (size_t)-1, TRUE); + + if (!sigchld_handler_set) { + sigchld_handler_set = TRUE; + lib_signals_set_handler(SIGCHLD, TRUE, sigchld_handler, NULL); + } } static enum helper_result