Was cooking for almost one month and seems to work fine.
manual: Move /var/paraslash instructions to Troubleshooting.
Abstract sockets for server and audiod.
create_local_socket(): Avoid code duplication.
net.c: Combine remote_name() and __get_sock_name().
Remove socket address parameter of create_local_socket().
NEWS
====
+-----------------------------------------
+current master branch "magnetic momentum"
+-----------------------------------------
+ - On Linux systems, local sockets are now created in the
+ abstract name space by default. This allows to get rid of
+ the socket specials in /var/paraslash.
+
+Download: ./releases/paraslash-git.tar.bz2 (tarball)
------------------------------------------
0.5.4 (2015-01-23) "exponential alignment"
------------------------------------------
#include "ipc.h"
#include "list.h"
#include "sched.h"
-#include "signal.h"
#include "fd.h"
+#include "signal.h"
#include "mood.h"
#include "sideband.h"
#include "command.h"
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 */
return ret;
}
-static void signal_pre_select(struct sched *s, void *context)
-{
- struct signal_task *st = context;
- para_fd_set(st->fd, &s->rfds, &s->max_fileno);
-}
-
static int afs_signal_post_select(struct sched *s, __a_unused void *context)
{
int signum, ret;
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);
exit(EXIT_FAILURE);
}
-static void signal_pre_select(struct sched *s, void *context)
-{
- struct signal_task *st = context;
- para_fd_set(st->fd, &s->rfds, &s->max_fileno);
-}
-
static int signal_post_select(struct sched *s, void *context)
{
struct signal_task *st = context;
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));
return 0;
}
-static void signal_pre_select(struct sched *s, void *context)
-{
- struct signal_task *st = context;
- para_fd_set(st->fd, &s->rfds, &s->max_fileno);
-}
-
static void print_scroll_msg(void)
{
unsigned lines_total, filled = ringbuffer_filled(bot_win_rb);
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;
}
/** \file interactive.c Readline abstraction for interactive sessions. */
+#include "para.h"
+
#include <regex.h>
-#include <curses.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <sys/ioctl.h>
#include <signal.h>
-#include "para.h"
#include "fd.h"
#include "buffer_tree.h"
#include "list.h"
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 {
exit(EXIT_FAILURE);
}
-static void signal_pre_select(struct sched *s, void *context)
-{
- struct signal_task *st = context;
- para_fd_set(st->fd, &s->rfds, &s->max_fileno);
-}
-
/*
* called when server gets SIGHUP or when client invokes hup command.
*/
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);
}
struct task *task;
};
-int para_signal_init(void);
+_static_inline_ void signal_pre_select(struct sched *s, void *context)
+{
+ struct signal_task *st = context;
+ para_fd_set(st->fd, &s->rfds, &s->max_fileno);
+}
+
+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);