summaryrefslogtreecommitdiff
path: root/source3/lib/server_prefork.c
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2011-08-17 10:53:38 -0400
committerSimo Sorce <idra@samba.org>2011-08-21 09:05:05 -0400
commit0f71639d3348391b672c9da78f4341785bfd6754 (patch)
tree97325d0828caed15278dc34f622224fde85cf74f /source3/lib/server_prefork.c
parent75f3da76e48df79c21e65354768d3f581053127e (diff)
downloadsamba-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/lib/server_prefork.c')
-rw-r--r--source3/lib/server_prefork.c34
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);
}