#include "includes.h"
#include "lib/events/events.h"
#include "../tdb/include/tdb.h"
-#include "lib/socket/socket.h"
#include "smbd/process_model.h"
-#include "param/secrets.h"
#include "system/filesys.h"
#include "cluster/cluster.h"
#include "param/param.h"
}
#endif
+/* we hold a pipe open in the parent, and the any child
+ processes wait for EOF on that pipe. This ensures that
+ children die when the parent dies */
+static int child_pipe[2];
+
/*
called when the process model is selected
*/
-static void standard_model_init(struct event_context *ev)
+static void standard_model_init(struct tevent_context *ev)
{
+ pipe(child_pipe);
signal(SIGCHLD, SIG_IGN);
}
+/*
+ handle EOF on the child pipe
+*/
+static void standard_pipe_handler(struct tevent_context *event_ctx, struct tevent_fd *fde,
+ uint16_t flags, void *private_data)
+{
+ DEBUG(10,("Child %d exiting\n", (int)getpid()));
+ exit(0);
+}
+
/*
called when a listening socket becomes readable.
*/
-static void standard_accept_connection(struct event_context *ev,
+static void standard_accept_connection(struct tevent_context *ev,
struct loadparm_context *lp_ctx,
struct socket_context *sock,
- void (*new_conn)(struct event_context *,
+ void (*new_conn)(struct tevent_context *,
struct loadparm_context *, struct socket_context *,
struct server_id , void *),
- void *private)
+ void *private_data)
{
NTSTATUS status;
struct socket_context *sock2;
pid_t pid;
- struct event_context *ev2;
+ struct tevent_context *ev2;
struct socket_address *c, *s;
/* accept an incoming connection. */
/* 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);
- talloc_steal(private, sock2);
+ talloc_steal(ev2, private_data);
+ talloc_steal(private_data, sock2);
/* this will free all the listening sockets and all state that
is not associated with this new connection */
DEBUG(0,("standard_accept_connection: tdb_reopen_all failed.\n"));
}
+ tevent_add_fd(ev2, ev2, child_pipe[0], TEVENT_FD_READ,
+ standard_pipe_handler, NULL);
+ close(child_pipe[1]);
+
/* Ensure that the forked children do not expose identical random streams */
set_need_random_reseed();
talloc_free(s);
/* setup this new connection. Cluster ID is PID based for this process modal */
- new_conn(ev2, lp_ctx, sock2, cluster_id(pid, 0), private);
+ new_conn(ev2, lp_ctx, sock2, cluster_id(pid, 0), private_data);
/* 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
/*
called to create a new server task
*/
-static void standard_new_task(struct event_context *ev,
+static void standard_new_task(struct tevent_context *ev,
struct loadparm_context *lp_ctx,
const char *service_name,
- void (*new_task)(struct event_context *, struct loadparm_context *lp_ctx, struct server_id , void *),
- void *private)
+ void (*new_task)(struct tevent_context *, struct loadparm_context *lp_ctx, struct server_id , void *),
+ void *private_data)
{
pid_t pid;
- struct event_context *ev2;
+ struct tevent_context *ev2;
pid = fork();
/* 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);
+ talloc_steal(ev2, private_data);
/* this will free all the listening sockets and all state that
is not associated with this new connection */
DEBUG(0,("standard_accept_connection: tdb_reopen_all failed.\n"));
}
+ tevent_add_fd(ev2, ev2, child_pipe[0], TEVENT_FD_READ,
+ standard_pipe_handler, NULL);
+ close(child_pipe[1]);
+
/* Ensure that the forked children do not expose identical random streams */
set_need_random_reseed();
setproctitle("task %s server_id[%d]", service_name, pid);
/* setup this new task. Cluster ID is PID based for this process modal */
- new_task(ev2, lp_ctx, cluster_id(pid, 0), private);
+ new_task(ev2, lp_ctx, cluster_id(pid, 0), private_data);
/* 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
/* called when a task goes down */
-_NORETURN_ static void standard_terminate(struct event_context *ev, const char *reason)
+_NORETURN_ static void standard_terminate(struct tevent_context *ev, struct loadparm_context *lp_ctx,
+ const char *reason)
{
DEBUG(2,("standard_terminate: reason[%s]\n",reason));
/* this reload_charcnv() has the effect of freeing the iconv context memory,
which makes leak checking easier */
- reload_charcnv(global_loadparm);
+ reload_charcnv(lp_ctx);
talloc_free(ev);
}
/* called to set a title of a task or connection */
-static void standard_set_title(struct event_context *ev, const char *title)
+static void standard_set_title(struct tevent_context *ev, const char *title)
{
if (title) {
setproctitle("%s", title);