+static void smbd_sig_chld_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ pid_t pid;
+ int status;
+
+ while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) {
+ bool unclean_shutdown = False;
+
+ /* If the child terminated normally, assume
+ it was an unclean shutdown unless the
+ status is 0
+ */
+ if (WIFEXITED(status)) {
+ unclean_shutdown = WEXITSTATUS(status);
+ }
+ /* If the child terminated due to a signal
+ we always assume it was unclean.
+ */
+ if (WIFSIGNALED(status)) {
+ unclean_shutdown = True;
+ }
+ remove_child_pid(pid, unclean_shutdown);
+ }
+}
+
+static void smbd_setup_sig_chld_handler(void)
+{
+ struct tevent_signal *se;
+
+ se = tevent_add_signal(smbd_event_context(),
+ smbd_event_context(),
+ SIGCHLD, 0,
+ smbd_sig_chld_handler,
+ NULL);
+ if (!se) {
+ exit_server("failed to setup SIGCHLD handler");
+ }
+}
+