Merge branch 't/gui_improvements'
[paraslash.git] / audioc.c
index 73bc2cf36bc0bbd51f43490548c2241e65bf13b0..74fb11cb0622cbab54f5c46ce28cbd5856efffe8 100644 (file)
--- a/audioc.c
+++ b/audioc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2011 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2005-2013 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -9,6 +9,7 @@
 #include <regex.h>
 #include <sys/types.h>
 #include <stdbool.h>
+#include <signal.h>
 
 #include "audioc.cmdline.h"
 #include "para.h"
@@ -105,7 +106,7 @@ static void audioc_pre_select(struct sched *s, struct task *t)
        para_fd_set(at->fd, &s->rfds, &s->max_fileno);
 }
 
-static void audioc_post_select(struct sched *s, struct task *t)
+static int audioc_post_select(struct sched *s, struct task *t)
 {
        char *buf = NULL;
        struct audioc_task *at = container_of(t, struct audioc_task, task);
@@ -114,7 +115,7 @@ static void audioc_post_select(struct sched *s, struct task *t)
        if (ret < 0)
                goto out;
        if (!FD_ISSET(at->fd, &s->rfds))
-               return;
+               return 0;
        buf = para_malloc(conf.bufsize_arg);
        ret = recv_bin_buffer(at->fd, buf, conf.bufsize_arg);
        PARA_DEBUG_LOG("recv: %d\n", ret);
@@ -123,16 +124,14 @@ static void audioc_post_select(struct sched *s, struct task *t)
        if (ret < 0)
                goto out;
        btr_add_output(buf, ret, at->btrn);
-       return;
+       return 0;
 out:
        if (ret < 0) {
                free(buf);
-               btr_remove_node(at->btrn);
-               btr_free_node(at->btrn);
-               at->btrn = NULL;
+               btr_remove_node(&at->btrn);
                close(at->fd);
        }
-       t->error = ret;
+       return ret;
 }
 
 static struct audioc_task audioc_task = {
@@ -252,16 +251,15 @@ __noreturn static void print_completions(void)
 
 static char *configfile_exists(void)
 {
-       static char *config_file;
+       char *config_file;
        struct stat statbuf;
+       char *home = para_homedir();
 
-       if (!config_file) {
-               char *home = para_homedir();
-               config_file = make_message("%s/.paraslash/audioc.conf", home);
-               free(home);
-       }
+       config_file = make_message("%s/.paraslash/audioc.conf", home);
+       free(home);
        if (!stat(config_file, &statbuf))
                return config_file;
+       free(config_file);
        return NULL;
 }
 
@@ -271,10 +269,11 @@ static char *configfile_exists(void)
  * \param argc Usual argument count.
  * \param argv Usual argument vector.
  *
- * It creates a temporary local socket in order to communicate with para_audiod.
- * Authentication consists in sending a ucred buffer that contains the user id.
+ * It connects to the "well-known" local socket to communicate with
+ * para_audiod. Authentication is performed by sending a ucred buffer
+ * containing the user id to the local socket.
  *
- * Any output received through the local socket is sent to stdout.
+ * Any data received from the socket is written to stdout.
  *
  * \return EXIT_SUCCESS or EXIT_FAILURE.
  *
@@ -283,7 +282,7 @@ static char *configfile_exists(void)
 int main(int argc, char *argv[])
 {
        int ret = -E_AUDIOC_SYNTAX, fd;
-       char *cf, *buf = NULL, *args;
+       char *cf, *buf = NULL, *args = NULL;
        size_t bufsize;
 
        if (audioc_cmdline_parser(argc, argv, &conf))
@@ -297,7 +296,9 @@ int main(int argc, char *argv[])
                        .check_required = 0,
                        .check_ambiguity = 0
                };
-               if (audioc_cmdline_parser_config_file(cf, &conf, &params)) {
+               ret = audioc_cmdline_parser_config_file(cf, &conf, &params);
+               free(cf);
+               if (ret) {
                        fprintf(stderr, "parse error in config file\n");
                        exit(EXIT_FAILURE);
                }
@@ -331,13 +332,18 @@ int main(int argc, char *argv[])
                goto out;
        bufsize = conf.bufsize_arg;
        buf = para_malloc(bufsize);
+       ret = mark_fd_blocking(STDOUT_FILENO);
+       if (ret < 0)
+               goto out;
        do {
                size_t n = ret = recv_bin_buffer(fd, buf, bufsize);
                if (ret <= 0)
                        break;
-               ret = write_all(STDOUT_FILENO, buf, &n);
+               ret = write_all(STDOUT_FILENO, buf, n);
        } while (ret >= 0);
 out:
+       free(buf);
+       free(args);
        if (ret < 0)
                PARA_ERROR_LOG("%s\n", para_strerror(-ret));
        return ret < 0? EXIT_FAILURE : EXIT_SUCCESS;