+ struct signal_task *st = container_of(t, struct signal_task, task);
+ para_fd_set(st->fd, &s->rfds, &s->max_fileno);
+}
+
+/*
+ * called when server gets SIGHUP or when client invokes hup command.
+ */
+static void handle_sighup(void)
+{
+ PARA_NOTICE_LOG("SIGHUP\n");
+ close_log(logfile); /* gets reopened if necessary by parse_config */
+ logfile = NULL;
+ parse_config(1); /* reopens log */
+ init_user_list(user_list_file); /* reload user list */
+ if (mmd->afs_pid)
+ kill(mmd->afs_pid, SIGHUP);
+}
+
+static void signal_post_select(struct sched *s, struct task *t)
+{
+ struct signal_task *st = container_of(t, struct signal_task, task);
+
+ if (!FD_ISSET(st->fd, &s->rfds))
+ return;
+
+ st->signum = para_next_signal();
+ switch (st->signum) {
+ case SIGHUP:
+ handle_sighup();
+ break;
+ case SIGCHLD:
+ for (;;) {
+ pid_t pid;
+ int ret = para_reap_child(&pid);
+ if (ret <= 0)
+ break;
+ if (pid != mmd->afs_pid)
+ continue;
+ PARA_EMERG_LOG("fatal: afs died\n");
+ goto genocide;
+ }
+ break;
+ /* die on sigint/sigterm. Kill all children too. */
+ case SIGINT:
+ case SIGTERM:
+ PARA_EMERG_LOG("terminating on signal %d\n", st->signum);
+genocide:
+ kill(0, SIGTERM);
+ mutex_destroy(mmd_mutex);
+ shm_detach(mmd);
+ shm_destroy(mmd_shm_id);
+
+ exit(EXIT_FAILURE);
+ }
+}
+
+static void init_signal_task(void)
+{
+ static struct signal_task signal_task_struct,
+ *st = &signal_task_struct;
+
+ st->task.pre_select = signal_pre_select;
+ st->task.post_select = signal_post_select;
+ sprintf(st->task.status, "signal task");
+
+ st->fd = para_signal_init(); /* always successful */