summaryrefslogtreecommitdiff
path: root/source4/smbd/process_standard.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/smbd/process_standard.c')
-rw-r--r--source4/smbd/process_standard.c58
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,
};
/*