]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 'refs/heads/t/abtract_sockets'
authorAndre Noll <maan@tuebingen.mpg.de>
Sun, 8 Mar 2015 18:32:37 +0000 (19:32 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 8 Mar 2015 18:43:44 +0000 (19:43 +0100)
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().

1  2 
NEWS
afs.c
audiod.c

diff --combined NEWS
index cf301a2dde17284d19899c1f2670ebb73737bb90,cf301a2dde17284d19899c1f2670ebb73737bb90..b29d4b828ed1245b59795927667d3c6470d10332
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,6 -1,6 +1,14 @@@
  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"
  ------------------------------------------
diff --combined afs.c
index 96621e4b62aa52b575f8881e1f5ba826f44259d7,65d6ed958d17d3238c5b55535bf661ec782d5c5f..c5e2c93ee51363a69f3178b77c4d79982b427f73
--- 1/afs.c
--- 2/afs.c
+++ b/afs.c
@@@ -28,8 -28,8 +28,8 @@@
  #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"
@@@ -89,7 -89,7 +89,7 @@@ extern struct misc_meta_data *mmd
  
  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 */
@@@ -637,25 -637,19 +637,19 @@@ static int setup_command_socket_or_die(
  {
        int ret, socket_fd;
        char *socket_name = conf.afs_socket_arg;
-       struct sockaddr_un unix_addr;
  
        unlink(socket_name);
-       ret = create_local_socket(socket_name, &unix_addr,
-               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH);
+       ret = create_local_socket(socket_name, 0);
        if (ret < 0) {
-               PARA_EMERG_LOG("%s: %s\n", para_strerror(-ret), socket_name);
-               exit(EXIT_FAILURE);
+               ret = create_local_socket(socket_name,
+                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH);
+               if (ret < 0) {
+                       PARA_EMERG_LOG("%s: %s\n", para_strerror(-ret),
+                               socket_name);
+                       exit(EXIT_FAILURE);
+               }
        }
        socket_fd = ret;
-       if (listen(socket_fd , 5) < 0) {
-               PARA_EMERG_LOG("can not listen on socket\n");
-               exit(EXIT_FAILURE);
-       }
-       ret = mark_fd_nonblocking(socket_fd);
-       if (ret < 0) {
-               close(socket_fd);
-               return ret;
-       }
        PARA_INFO_LOG("listening on socket %s (fd %d)\n", socket_name,
                socket_fd);
        return socket_fd;
@@@ -719,6 -713,12 +713,6 @@@ static int open_afs_tables(void
        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;
@@@ -747,17 -747,20 +741,17 @@@ shutdown
  
  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);
  }
diff --combined audiod.c
index 3f83b984a8215208e1247aade01e06c421e745a6,acf41376f50f196414d327bfb11f506c4fe8d7e2..8f246ba53a04bad687af14d428bec276c822f001
+++ b/audiod.c
@@@ -144,7 -144,7 +144,7 @@@ struct audiod_args_info conf
  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 struct status_task *stat_task = &status_task_struct;
  
- /**
-  * the task for handling audiod commands
+ /*
+  * The task for handling audiod commands.
+  *
+  * We need two listening sockets for backward compability: on Linux systems
+  * fd[0] is an abstract socket (more precisely, a socket bound to an address in
+  * the abstract namespace), and fd[1] is the usual pathname socket. On other
+  * systems, fd[0] is negative, and only the pathname socket is used.
   *
-  * \sa struct task, struct sched
+  * For 0.5.x we accept connections on both sockets to make sure that old
+  * para_audioc versions can still connect. New versions use only the abstract
+  * socket. Hence after v0.6.0 we can go back to a single socket, either an
+  * abstract one (Linux) or a pathname socket (all other systems).
   */
  struct command_task {
-       /** the local listening socket */
-       int fd;
+       /** The local listening sockets. */
+       int fd[2];
        /** the associated task structure */
        struct task *task;
  };
@@@ -347,7 -355,8 +355,7 @@@ err
  
  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);
@@@ -955,11 -964,8 +963,8 @@@ static int parse_stream_args(void
  }
  
  /* does not unlink socket on errors */
- static int audiod_get_socket(void)
+ static void init_local_sockets(struct command_task *ct)
  {
-       struct sockaddr_un unix_addr;
-       int ret, fd;
        if (conf.socket_given)
                socket_name = para_strdup(conf.socket_arg);
        else {
        PARA_NOTICE_LOG("local socket: %s\n", socket_name);
        if (conf.force_given)
                unlink(socket_name);
-       ret = create_local_socket(socket_name, &unix_addr,
+       ct->fd[0] = create_local_socket(socket_name, 0);
+       ct->fd[1] = create_local_socket(socket_name,
                S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH);
-       if (ret < 0)
-               goto err;
-       fd = ret;
-       if (listen(fd , 5) < 0) {
-               ret = -ERRNO_TO_PARA_ERROR(errno);
-               goto err;
-       }
-       ret = mark_fd_nonblocking(fd);
-       if (ret < 0)
-               goto err;
-       return fd;
- err:
-       PARA_EMERG_LOG("%s\n", para_strerror(-ret));
+       if (ct->fd[0] >= 0 || ct->fd[1] >= 0)
+               return;
+       PARA_EMERG_LOG("%s\n", para_strerror(-ct->fd[1]));
        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;
  static void command_pre_select(struct sched *s, void *context)
  {
        struct command_task *ct = context;
-       para_fd_set(ct->fd, &s->rfds, &s->max_fileno);
+       int i;
+       for (i = 0; i < 2; i++)
+               if (ct->fd[i] >= 0)
+                       para_fd_set(ct->fd[i], &s->rfds, &s->max_fileno);
  }
  
  static int command_post_select(struct sched *s, void *context)
  {
-       int ret;
+       int ret, i;
        struct command_task *ct = context;
        static struct timeval last_status_dump;
        struct timeval tmp, delay;
-       bool force = true;
+       bool force = false;
  
        ret = task_get_notification(ct->task);
        if (ret < 0)
                return ret;
-       ret = handle_connect(ct->fd, &s->rfds);
-       if (ret < 0) {
-               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
-               if (ret == -E_AUDIOD_TERM) {
-                       task_notify_all(s, -ret);
-                       return ret;
-               }
-       } else if (ret > 0)
+       for (i = 0; i < 2; i++) {
+               if (ct->fd[i] < 0)
+                       continue;
+               ret = handle_connect(ct->fd[i], &s->rfds);
+               if (ret < 0) {
+                       PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+                       if (ret == -E_AUDIOD_TERM) {
+                               task_notify_all(s, -ret);
+                               return ret;
+                       }
+               } else if (ret > 0)
+                       force = true;
+       }
+       if (force == true)
                goto dump;
  
        /* if last status dump was less than 500ms ago, do nothing */
        delay.tv_sec = 5;
        delay.tv_usec = 0;
        tv_add(&last_status_dump, &delay, &tmp);
-       if (tv_diff(now, &tmp, NULL) < 0)
-               force = false;
+       if (tv_diff(now, &tmp, NULL) > 0)
+               force = true;
  dump:
        audiod_status_dump(force);
        last_status_dump = *now;
  
  static void init_command_task(struct command_task *ct)
  {
-       ct->fd = audiod_get_socket(); /* doesn't return on errors */
+       init_local_sockets(ct); /* doesn't return on errors */
  
        ct->task = task_register(&(struct task_info) {
                .name = "command",
@@@ -1405,11 -1418,11 +1411,11 @@@ int main(int argc, char *argv[]
        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));