diff options
Diffstat (limited to 'source4/smbd/process_standard.c')
-rw-r--r-- | source4/smbd/process_standard.c | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c index ee73cfadcf..b7e9076e5d 100644 --- a/source4/smbd/process_standard.c +++ b/source4/smbd/process_standard.c @@ -104,11 +104,60 @@ static void standard_accept_connection(struct event_context *ev, exit(0); } +/* + called to create a new server task +*/ +static void standard_new_task(struct event_context *ev, + void (*new_task)(struct event_context *, uint32_t , void *), + void *private) +{ + pid_t pid; + struct event_context *ev2; + + pid = fork(); + + if (pid != 0) { + /* parent or error code ... go back to the event loop */ + return; + } + + /* This is now the child code. We need a completely new event_context to work with */ + ev2 = event_context_init(NULL); + + /* the service has given us a private pointer that + encapsulates the context it needs for this new connection - + everything else will be freed */ + talloc_steal(ev2, private); + + /* this will free all the listening sockets and all state that + is not associated with this new connection */ + talloc_free(ev); + + /* tdb needs special fork handling */ + if (tdb_reopen_all() == -1) { + DEBUG(0,("standard_accept_connection: tdb_reopen_all failed.\n")); + } + + /* Ensure that the forked children do not expose identical random streams */ + set_need_random_reseed(); + + /* setup this new connection */ + new_task(ev2, getpid(), private); + + /* we can't return to the top level here, as that event context is gone, + so we now process events in the new event context until there are no + more to process */ + event_loop_wait(ev2); + + talloc_free(ev2); + exit(0); +} + -/* called when a connection goes down */ -static void standard_terminate_connection(struct event_context *ev, const char *reason) +/* called when a task goes down */ +static void standard_terminate(struct event_context *ev, const char *reason) { - DEBUG(2,("standard_terminate_connection: reason[%s]\n",reason)); + DEBUG(2,("standard_terminate: reason[%s]\n",reason)); /* this init_iconv() has the effect of freeing the iconv context memory, which makes leak checking easier */ @@ -128,7 +177,8 @@ static const struct model_ops standard_ops = { .name = "standard", .model_init = standard_model_init, .accept_connection = standard_accept_connection, - .terminate_connection = standard_terminate_connection, + .new_task = standard_new_task, + .terminate = standard_terminate, }; /* |