diff options
author | Simo Sorce <idra@samba.org> | 2011-08-17 10:53:38 -0400 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2011-08-21 09:05:05 -0400 |
commit | 0f71639d3348391b672c9da78f4341785bfd6754 (patch) | |
tree | 97325d0828caed15278dc34f622224fde85cf74f /source3 | |
parent | 75f3da76e48df79c21e65354768d3f581053127e (diff) | |
download | samba-0f71639d3348391b672c9da78f4341785bfd6754.tar.gz samba-0f71639d3348391b672c9da78f4341785bfd6754.tar.bz2 samba-0f71639d3348391b672c9da78f4341785bfd6754.zip |
s3-prefork: Improve error detection when handling new connections
Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Simo Sorce <idra@samba.org>
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/server_prefork.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c index d63e6a1673..82645504f8 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); } |