#include "audiod.cmdline.h"
#include "list.h"
-#include "close_on_fork.h"
#include "sched.h"
#include "recv.h"
#include "filter.h"
#include "grab_client.cmdline.h"
#include "grab_client.h"
-
-#include "error.h"
+#include "client.cmdline.h"
+#include "client.h"
#include "audiod.h"
#include "net.h"
#include "daemon.h"
#include "fd.h"
#include "write.h"
#include "write_common.h"
+#include "error.h"
/** define the array of error lists needed by para_audiod */
INIT_AUDIOD_ERRLISTS;
int audiod_status = AUDIOD_ON;
-struct gengetopt_args_info conf;
+struct audiod_args_info conf;
static char *socket_name;
static FILE *logfile;
static struct audio_format_info afi[NUM_AUDIO_FORMATS];
struct task task;
};
+/**
+ * task for signal handling
+ */
struct signal_task {
+ /** the signal pipe */
int fd;
+ /** the number of the most recent signal */
int signum;
+ /** the associated task structure */
struct task task;
};
PARA_INFO_LOG("signal pipe: fd %d\n", sig_task->fd);
para_install_sighandler(SIGINT);
para_install_sighandler(SIGTERM);
- para_install_sighandler(SIGCHLD);
para_install_sighandler(SIGHUP);
- para_install_sighandler(SIGPIPE);
-// signal(SIGPIPE, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
}
static void clear_slot(int slot_num)
{
int i;
- if (stat_task->fd < 0)
+ if (!stat_task->pcd)
return;
- PARA_NOTICE_LOG("%s", "closing status pipe\n");
- close(stat_task->fd);
- del_close_on_fork_list(stat_task->fd);
- stat_task->fd = -1;
-// kill_all_decoders();
+ client_close(stat_task->pcd);
+ stat_task->pcd = NULL;
for (i = 0; i < NUM_STAT_ITEMS; i++) {
free(stat_task->stat_item_values[i]);
stat_task->stat_item_values[i] = NULL;
PARA_EMERG_LOG("%s\n", msg);
if (socket_name)
unlink(socket_name);
- if (stat_task->fd >= 0)
- close_stat_pipe();
+ close_stat_pipe();
exit(status);
}
int i;
struct timeval diff;
- if (!stat_task->af_status)
+ if (!stat_task->af_status || !stat_task->pcd)
return 0;
i = get_audio_format_num(stat_task->af_status);
if (i < 0)
static void handle_signal(int sig)
{
switch (sig) {
- case SIGCHLD:
- for (;;) {
- pid_t pid = para_reap_child();
- if (pid <= 0)
- return;
- PARA_CRIT_LOG("para_client died (pid %d)\n", pid);
- }
case SIGINT:
case SIGTERM:
case SIGHUP:
PARA_EMERG_LOG("%s", "can not listen on socket\n");
exit(EXIT_FAILURE); /* do not unlink socket */
}
- add_close_on_fork_list(fd);
+ mark_fd_nonblock(fd);
return fd;
}
-static int open_stat_pipe(void)
-{
- int ret, fd[3] = {-1, 1, 0};
- pid_t pid;
- ret = para_exec_cmdline_pid(&pid, BINDIR "/para_client stat", fd);
- if (ret >= 0) {
- ret = fd[1];
- PARA_NOTICE_LOG("stat pipe opened, fd %d\n", ret);
- add_close_on_fork_list(ret);
- } else
- clean_exit(EXIT_FAILURE, "failed to open status pipe");
- return ret;
-}
-
-void signal_event_handler(struct task *t)
+static void signal_event_handler(struct task *t)
{
struct signal_task *st = t->private_data;
handle_signal(st->signum);
}
-void signal_pre_select(struct sched *s, struct task *t)
+static void signal_pre_select(struct sched *s, struct task *t)
{
struct signal_task *st = t->private_data;
t->ret = 1;
para_fd_set(st->fd, &s->rfds, &s->max_fileno);
}
-void signal_post_select(struct sched *s, struct task *t)
+static void signal_post_select(struct sched *s, struct task *t)
{
struct signal_task *st = t->private_data;
t->ret = 1;
st->signum = para_next_signal();
}
-void signal_setup_default(struct signal_task *st)
+static void signal_setup_default(struct signal_task *st)
{
st->task.pre_select = signal_pre_select;
st->task.post_select = signal_post_select;
sprintf(ct->task.status, "command task");
}
+static void client_task_event_handler(__a_unused struct task *t)
+{
+ struct private_client_data *pcd = t->private_data;
+ if (t->ret == -E_HANDSHAKE_COMPLETE)
+ return;
+ unregister_task(t);
+ pcd->eof = 1;
+}
+
static void status_event_handler(__a_unused struct task *t)
{
struct timeval delay = {1, 0};
static void status_pre_select(struct sched *s, struct task *t)
{
struct status_task *st = t->private_data;
+ int argc = 2;
+ char *argv[] = {"audiod", "stat", NULL};
t->ret = 1;
- if (st->fd >= 0 && audiod_status == AUDIOD_OFF)
+ if (st->pcd && (audiod_status == AUDIOD_OFF || st->pcd->eof))
close_stat_pipe();
- if (st->fd < 0 && audiod_status != AUDIOD_OFF
+ if (!st->pcd && audiod_status != AUDIOD_OFF
&& tv_diff(now, &st->restart_barrier, NULL) > 0) {
- st->fd = open_stat_pipe();
- st->loaded = 0;
- st->buf[0] = '\0';
+ t->ret = client_parse_config(argc, argv, &st->pcd);
+ if (t->ret < 0)
+ return;
+ t->ret = client_open(st->pcd);
+ if (t->ret < 0)
+ return;
+ st->pcd->task.event_handler = client_task_event_handler;
+ s->timeout.tv_sec = 0;
+ s->timeout.tv_usec = 1;
}
- if (st->fd >= 0 && audiod_status != AUDIOD_OFF)
- para_fd_set(st->fd, &s->rfds, &s->max_fileno);
}
-static void status_post_select(struct sched *s, struct task *t)
+static void status_post_select(__a_unused struct sched *s, struct task *t)
{
struct status_task *st = t->private_data;
t->ret = 1;
- if (st->fd < 0 || !FD_ISSET(st->fd, &s->rfds))
+ if (!st->pcd || !st->pcd->loaded
+ || st->pcd->status != CL_RECEIVING)
return;
- t->ret = read(st->fd, st->buf + st->loaded, STRINGSIZE - 1 - st->loaded);
- if (t->ret <= 0) {
- if (!t->ret)
- t->ret = -E_STATUS_EOF;
- return;
- }
- st->buf[t->ret + st->loaded] = '\0';
- st->loaded = for_each_line(st->buf, t->ret + st->loaded,
+ st->pcd->loaded = for_each_line(st->pcd->buf, st->pcd->loaded,
&check_stat_line);
}
st->task.post_select = status_post_select;
st->task.event_handler = status_event_handler;
st->task.private_data = st;
- st->fd = -1;
st->sa_time_diff_sign = 1;
sprintf(st->task.status, "status task");
}
struct task audiod_task_struct, *audiod_task = &audiod_task_struct;
valid_fd_012();
- cmdline_parser(argc, argv, &conf);
+ audiod_cmdline_parser(argc, argv, &conf);
para_drop_privileges(conf.user_arg, conf.group_arg);
cf = configfile_exists();
if (cf) {
- if (cmdline_parser_configfile(cf, &conf, 0, 0, 0)) {
+ if (audiod_cmdline_parser_configfile(cf, &conf, 0, 0, 0)) {
PARA_EMERG_LOG("%s", "parse error in config file\n");
exit(EXIT_FAILURE);
}
register_task(&cmd_task->task);
register_task(&stat_task->task);
register_task(audiod_task);
- s.default_timeout.tv_sec = 3;
+ s.default_timeout.tv_sec = 0;
s.default_timeout.tv_usec = 99 * 1000;
ret = sched(&s);