From: Simo Sorce Date: Wed, 17 Aug 2011 14:53:38 +0000 (-0400) Subject: s3-prefork: Improve error detection when handling new connections X-Git-Tag: samba-4.0.0alpha17~448 X-Git-Url: http://git.samba.org/samba.git/?p=ambi%2Fsamba-autobuild%2F.git;a=commitdiff_plain;h=0f71639d3348391b672c9da78f4341785bfd6754 s3-prefork: Improve error detection when handling new connections Signed-off-by: Andreas Schneider Signed-off-by: Simo Sorce --- diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c index d63e6a16738..82645504f8e 100644 --- a/source3/lib/server_prefork.c +++ b/source3/lib/server_prefork.c @@ -553,7 +553,8 @@ static void prefork_listen_accept_handler(struct tevent_context *ev, struct pf_listen_ctx *ctx; struct sockaddr_storage addr; socklen_t addrlen; - int err = 0; + int soerr = 0; + socklen_t solen = sizeof(soerr); int sd = -1; int ret; @@ -564,24 +565,33 @@ static void prefork_listen_accept_handler(struct tevent_context *ev, if (state->pf->cmds == PF_SRV_MSG_EXIT) { /* We have been asked to exit, so drop here and the next * child will pick it up */ - state->pf->status = PF_WORKER_EXITING; + if (state->pf->num_clients <= 0) { + state->pf->status = PF_WORKER_EXITING; + } state->error = EINTR; goto done; } + /* before proceeding check that the listening fd is ok */ + ret = getsockopt(ctx->listen_fd, SOL_SOCKET, SO_ERROR, &soerr, &solen); + if (ret == -1) { + /* this is a fatal error, we cannot continue listening */ + state->error = EBADF; + goto done; + } + if (soerr != 0) { + /* this is a fatal error, we cannot continue listening */ + state->error = soerr; + goto done; + } + ZERO_STRUCT(addr); addrlen = sizeof(addr); sd = accept(ctx->listen_fd, (struct sockaddr *)&addr, &addrlen); if (sd == -1) { - err = errno; - DEBUG(6, ("Accept failed! (%d, %s)\n", err, strerror(err))); - } - - /* do not track the listen fds anymore */ - talloc_free(ctx->fde_ctx); - ctx = NULL; - if (err) { - state->error = err; + state->error = errno; + DEBUG(6, ("Accept failed! (%d, %s)\n", + state->error, strerror(state->error))); goto done; } @@ -612,6 +622,8 @@ static void prefork_listen_accept_handler(struct tevent_context *ev, } done: + /* do not track the listen fds anymore */ + talloc_free(ctx->fde_ctx); tevent_req_done(req); }