static int server_socket;
static struct command_task command_task_struct;
-static struct signal_task signal_task_struct;
+static struct signal_task *signal_task;
static enum play_mode current_play_mode;
static char *current_mop; /* mode or playlist specifier. NULL means dummy mood */
static void register_signal_task(struct sched *s)
{
- struct signal_task *st = &signal_task_struct;
-
para_sigaction(SIGPIPE, SIG_IGN);
- st->fd = para_signal_init();
- PARA_INFO_LOG("signal pipe: fd %d\n", st->fd);
+ signal_task = signal_init_or_die();
para_install_sighandler(SIGINT);
para_install_sighandler(SIGTERM);
para_install_sighandler(SIGHUP);
- st->task = task_register(&(struct task_info) {
+ signal_task->task = task_register(&(struct task_info) {
.name = "signal",
.pre_select = signal_pre_select,
.post_select = afs_signal_post_select,
- .context = st,
+ .context = signal_task,
}, s);
}
static char *socket_name;
static struct audio_format_info afi[NUM_AUDIO_FORMATS];
-static struct signal_task signal_task_struct, *sig_task = &signal_task_struct;
+static struct signal_task *signal_task;
static struct status_task status_task_struct;
static void setup_signal_handling(void)
{
- sig_task->fd = para_signal_init();
- PARA_INFO_LOG("signal pipe: fd %d\n", sig_task->fd);
+ signal_task = signal_init_or_die();
para_install_sighandler(SIGINT);
para_install_sighandler(SIGTERM);
para_install_sighandler(SIGHUP);
if (conf.daemon_given)
daemonize(false /* parent exits immediately */);
- sig_task->task = task_register(&(struct task_info) {
+ signal_task->task = task_register(&(struct task_info) {
.name = "signal",
.pre_select = signal_pre_select,
.post_select = signal_post_select,
- .context = sig_task,
+ .context = signal_task,
}, &sched);
sched.default_timeout.tv_sec = 2;
ret = schedule(&sched);
audiod_cleanup();
sched_shutdown(&sched);
+ signal_shutdown(signal_task);
if (ret < 0)
PARA_EMERG_LOG("%s\n", para_strerror(-ret));
struct exec_task exec_task = {.task = NULL};
struct status_task status_task = {.fd = -1};
struct input_task input_task = {.task = NULL};
- struct signal_task signal_task = {.task = NULL};
+ struct signal_task *signal_task;
struct sched sched = {
.default_timeout = {
.tv_sec = conf.timeout_arg / 1000,
.context = &input_task,
}, &sched);
- signal_task.fd = para_signal_init();
+ signal_task = signal_init_or_die();
para_install_sighandler(SIGINT);
para_install_sighandler(SIGTERM);
para_install_sighandler(SIGCHLD);
para_install_sighandler(SIGUSR1);
- signal_task.task = task_register(&(struct task_info) {
+ signal_task->task = task_register(&(struct task_info) {
.name = "signal",
.pre_select = signal_pre_select,
.post_select = signal_post_select,
- .context = &signal_task,
+ .context = signal_task,
}, &sched);
ret = schedule(&sched);
sched_shutdown(&sched);
+ signal_shutdown(signal_task);
return ret;
}
static char *user_list_file = NULL;
static struct sched sched;
+static struct signal_task *signal_task;
/** The task responsible for server command handling. */
struct server_command_task {
static void init_signal_task(void)
{
- static struct signal_task signal_task_struct,
- *st = &signal_task_struct;
-
- PARA_NOTICE_LOG("setting up signal handling\n");
- st->fd = para_signal_init(); /* always successful */
+ signal_task = signal_init_or_die();
para_install_sighandler(SIGINT);
para_install_sighandler(SIGTERM);
para_install_sighandler(SIGHUP);
para_install_sighandler(SIGCHLD);
para_sigaction(SIGPIPE, SIG_IGN);
- add_close_on_fork_list(st->fd);
- st->task = task_register(&(struct task_info) {
+ add_close_on_fork_list(signal_task->fd);
+ signal_task->task = task_register(&(struct task_info) {
.name = "signal",
.pre_select = signal_pre_select,
.post_select = signal_post_select,
- .context = st,
+ .context = signal_task,
}, &sched);
}
free(chunk_table);
alarm(ALARM_TIMEOUT);
close_listed_fds();
- para_signal_shutdown();
+ signal_shutdown(signal_task);
/*
* put info on who we are serving into argv[0] to make
* client ip visible in top/ps
#include <signal.h>
#include <sys/types.h>
+#include <regex.h>
#include "para.h"
#include "error.h"
#include "fd.h"
#include "list.h"
+#include "string.h"
#include "sched.h"
#include "signal.h"
* ready for reading, see select(2).
*
* \return This function either succeeds or calls exit(2) to terminate the
- * current process. On success, the file descriptor of the read end of the
- * signal pipe is returned.
+ * current process. On success, a signal task structure is returned.
*/
-int para_signal_init(void)
+struct signal_task *signal_init_or_die(void)
{
+ struct signal_task *st;
int ret;
+
+ PARA_NOTICE_LOG("setting up signal handling\n");
if (pipe(signal_pipe) < 0) {
ret = -ERRNO_TO_PARA_ERROR(errno);
goto err_out;
ret = mark_fd_nonblocking(signal_pipe[1]);
if (ret < 0)
goto err_out;
- return signal_pipe[0];
+ st = para_calloc(sizeof(*st));
+ st->fd = signal_pipe[0];
+ return st;
err_out:
PARA_EMERG_LOG("%s\n", para_strerror(-ret));
exit(EXIT_FAILURE);
}
/**
- * Close the write end of the signal pipe.
+ * Close the write end of the signal pipe, deallocate resources.
+ *
+ * \param st The pointer obtained earlier from signal_init_or_die().
*/
-void para_signal_shutdown(void)
+void signal_shutdown(struct signal_task *st)
{
close(signal_pipe[1]);
+ free(st);
}
para_fd_set(st->fd, &s->rfds, &s->max_fileno);
}
-int para_signal_init(void);
+struct signal_task *signal_init_or_die(void);
void para_sigaction(int sig, void (*handler)(int));
void para_install_sighandler(int);
int para_reap_child(pid_t *pid);
int para_next_signal(fd_set *rfds);
-void para_signal_shutdown(void);
+void signal_shutdown(struct signal_task *st);
void para_block_signal(int sig);
void para_unblock_signal(int sig);