X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=12e8f7bb4345df416f2cdc0bc4c615fa7609129f;hp=0d8745d725bce902419afdd17c50a58cf51dd7fc;hb=41f13bf6cac519b46ed24892e2c84384ef5dc500;hpb=b99f2c1074bb0786c389830fc5c4db93a61a1dcc diff --git a/audiod.c b/audiod.c index 0d8745d7..12e8f7bb 100644 --- a/audiod.c +++ b/audiod.c @@ -111,24 +111,34 @@ static struct timeval *now; static struct signal_task signal_task_struct, *sig_task = &signal_task_struct; +/** + * the task for handling audiod commands + * + * \sa struct task, struct sched + */ struct command_task { + /** the local listening socket */ int fd; + /** the associated task structure */ struct task task; }; -static struct command_task command_task_struct, *cmd_task = &command_task_struct; +/** + * the task for audiod's child (para_client stat) + * + * \sa struct task, struct sched + */ struct status_task { + /** the output of the stat command is read from this fd */ int fd; - struct task task; + /** stat data is stored here */ char buf[STRINGSIZE]; + /** number of bytes loaded in \a buf */ unsigned loaded; -}; -static struct status_task status_task_struct, *stat_task = &status_task_struct; - -struct audiod_task { + /** the associated task structure */ struct task task; }; -static struct audiod_task audiod_task_struct, *at = &audiod_task_struct; +static struct status_task status_task_struct, *stat_task = &status_task_struct; struct signal_task { int fd; @@ -136,13 +146,17 @@ struct signal_task { struct task task; }; - /** defines one command of para_audiod */ struct audiod_command { /** the name of the command */ const char *name; /** pointer to the function that handles the command */ int (*handler)(int, int, char**); + /** + * if the command prefers to handle the full line (rather than the usual + * argv[] array), it stores a pointer to the corresponding line handling + * function here. In this case, the above \a handler pointer must be NULL. + */ int (*line_handler)(int, char*); /** one-line description of the command */ const char *description; @@ -553,7 +567,6 @@ static void close_stat_pipe(void) static void __noreturn clean_exit(int status, const char *msg) { PARA_EMERG_LOG("%s\n", msg); - kill_all_decoders(); if (socket_name) unlink(socket_name); if (stat_task->fd >= 0) @@ -689,7 +702,7 @@ static void open_writers(int slot_num) static void rn_event_handler(struct task *t) { -// struct receiver_node *rn = t->private_data; + struct receiver_node *rn = t->private_data; PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret)); unregister_task(t); } @@ -906,13 +919,14 @@ static void audiod_post_select(struct sched *s, __a_unused struct task *t) now = &s->now; } -static void init_audiod_task(struct audiod_task *at) +static void init_audiod_task(struct task *t) { - at->task.pre_select = audiod_pre_select; - at->task.post_select = audiod_post_select; - at->task.private_data = at; - at->task.flags = 0; - sprintf(at->task.status, "audiod task"); + t->pre_select = audiod_pre_select; + t->post_select = audiod_post_select; + t->event_handler = NULL; + t->private_data = t; + t->flags = 0; + sprintf(t->status, "audiod task"); } static int parse_stream_command(const char *txt, char **cmd) @@ -1335,13 +1349,13 @@ static int check_perms(uid_t uid) return -E_UCRED_PERM; } -static int handle_connect(void) +static int handle_connect(int accept_fd) { int i, argc, ret, clifd = -1; char *cmd = NULL, *p, *buf = para_calloc(MAXLINE), **argv = NULL; struct sockaddr_un unix_addr; - ret = para_accept(cmd_task->fd, &unix_addr, sizeof(struct sockaddr_un)); + ret = para_accept(accept_fd, &unix_addr, sizeof(struct sockaddr_un)); if (ret < 0) goto out; clifd = ret; @@ -1392,9 +1406,10 @@ out: return ret; } -static void audiod_get_socket(void) +static int audiod_get_socket(void) { struct sockaddr_un unix_addr; + int fd; if (conf.socket_given) socket_name = para_strdup(conf.socket_arg); @@ -1404,20 +1419,21 @@ static void audiod_get_socket(void) hn); free(hn); } - PARA_NOTICE_LOG("connecting to local socket %s\n", socket_name); + PARA_NOTICE_LOG("local socket: %s\n", socket_name); if (conf.force_given) unlink(socket_name); - cmd_task->fd = create_pf_socket(socket_name, &unix_addr, + fd = create_pf_socket(socket_name, &unix_addr, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH); - if (cmd_task->fd < 0) { + if (fd < 0) { PARA_EMERG_LOG("%s", "can not connect to socket\n"); exit(EXIT_FAILURE); /* do not unlink socket */ } - if (listen(cmd_task->fd , 5) < 0) { + if (listen(fd , 5) < 0) { PARA_EMERG_LOG("%s", "can not listen on socket\n"); exit(EXIT_FAILURE); /* do not unlink socket */ } - add_close_on_fork_list(cmd_task->fd); + add_close_on_fork_list(fd); + return fd; } static int open_stat_pipe(void) @@ -1483,7 +1499,7 @@ static void command_post_select(struct sched *s, struct task *t) t->ret = 1; /* always successful */ if (!FD_ISSET(ct->fd, &s->rfds)) return; - ret = handle_connect(); + ret = handle_connect(ct->fd); if (ret < 0) PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); } @@ -1492,8 +1508,10 @@ static void init_command_task(struct command_task *ct) { ct->task.pre_select = command_pre_select; ct->task.post_select = command_post_select; + ct->task.event_handler = NULL; ct->task.private_data = ct; ct->task.flags = 0; + ct->fd = audiod_get_socket(); /* doesn't return on errors */ sprintf(ct->task.status, "command task"); } @@ -1568,6 +1586,8 @@ int main(int argc, char *argv[]) char *cf; int ret, i; struct sched s; + struct command_task command_task_struct, *cmd_task = &command_task_struct; + struct task audiod_task_struct, *audiod_task = &audiod_task_struct; init_sched(); @@ -1596,21 +1616,20 @@ int main(int argc, char *argv[]) clear_slot(i); init_grabbing(); setup_signal_handling(); - if (conf.daemon_given) - daemon_init(); - audiod_get_socket(); /* doesn't return on errors */ - signal_setup_default(sig_task); sig_task->task.event_handler = signal_event_handler; init_status_task(stat_task); init_command_task(cmd_task); - init_audiod_task(at); + init_audiod_task(audiod_task); + + if (conf.daemon_given) + daemon_init(); register_task(&sig_task->task); register_task(&cmd_task->task); register_task(&stat_task->task); - register_task(&at->task); + register_task(audiod_task); s.default_timeout.tv_sec = 0; s.default_timeout.tv_usec = 99 * 1000; ret = sched(&s);