gui: Check return value of para_exec_cmdline_pid().
[paraslash.git] / write.c
diff --git a/write.c b/write.c
index dda1b70..a8e2429 100644 (file)
--- a/write.c
+++ b/write.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2011 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2005-2012 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -8,8 +8,6 @@
 
 #include <regex.h>
 #include <sys/types.h>
-#include <dirent.h>
-#include <stdbool.h>
 
 #include "para.h"
 #include "string.h"
@@ -23,6 +21,7 @@
 #include "write_common.h"
 #include "fd.h"
 #include "error.h"
+#include "version.h"
 
 INIT_WRITE_ERRLISTS;
 
@@ -165,17 +164,50 @@ __noreturn static void print_help_and_die(void)
        exit(0);
 }
 
-static int main_btr(struct sched *s)
+/*
+ * Parse config and register a task for a writer node.
+ *
+ * \param arg Command line arguments.
+ * \param parent The new node will be a child of \a parent.
+ * \param wn The writer node.
+ *
+ * If arg is \p NULL, the OS-dependent default writer is used with no
+ * arguments.  The default writers are alsa for Linux, osx for OS X, oss for
+ * *BSD, and the file writer if the default writer is not supported.
+ *
+ * Once the writer configuration has been retrieved from the ->parse_config
+ * callback a writer node is created, its buffer tree node is added to the
+ * buffer tree as a child of the given parent.
+ *
+ * Finally, the new writer node's task structure is initialized and registered
+ * to the paraslash scheduler.
+ *
+ * \return Standard.
+ */
+static void setup_writer_node(const char *arg, struct btr_node *parent,
+               struct writer_node *wn, struct sched *s)
+{
+       if (arg)
+               wn->conf = check_writer_arg_or_die(arg, &wn->writer_num);
+       else {
+               wn->writer_num = DEFAULT_WRITER;
+               wn->conf = writers[DEFAULT_WRITER].parse_config_or_die("");
+       }
+       register_writer_node(wn, parent, s);
+}
+
+static int setup_and_schedule(void)
 {
        int i, ret;
        struct check_wav_task _cwt, *cwt = &_cwt;
        struct writer_node *wns;
+       static struct sched s;
 
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
        sit.btrn = btr_new_node(&(struct btr_node_description)
                EMBRACE(.name = "stdin"));
        stdin_set_defaults(&sit);
-       register_task(&sit.task);
+       register_task(&s, &sit.task);
 
        cwt->state = CWS_NEED_HEADER;
        cwt->min_iqs = WAV_HEADER_LEN;
@@ -186,36 +218,43 @@ static int main_btr(struct sched *s)
        cwt->task.pre_select = check_wav_pre_select;
        cwt->task.post_select = check_wav_post_select;
        cwt->task.error = 0;
-       register_task(&cwt->task);
+       register_task(&s, &cwt->task);
 
-       ret = -E_WRITE_SYNTAX;
        if (!conf.writer_given) {
-               i = 0;
                wns = para_calloc(sizeof(*wns));
-               ret = setup_writer_node(NULL, cwt->btrn, wns);
-               if (ret < 0)
-                       goto out;
+               setup_writer_node(NULL, cwt->btrn, wns, &s);
                i = 1;
        } else {
                wns = para_calloc(conf.writer_given * sizeof(*wns));
-               for (i = 0; i < conf.writer_given; i++) {
-                       ret = setup_writer_node(conf.writer_arg[i],
-                               cwt->btrn, wns + i);
-                       if (ret < 0)
-                               goto out;
-               }
+               for (i = 0; i < conf.writer_given; i++)
+                       setup_writer_node(conf.writer_arg[i], cwt->btrn,
+                               wns + i, &s);
        }
 
-       s->default_timeout.tv_sec = 10;
-       s->default_timeout.tv_usec = 50000;
-       ret = schedule(s);
-out:
+       s.default_timeout.tv_sec = 10;
+       s.default_timeout.tv_usec = 50000;
+       ret = schedule(&s);
+       if (ret >= 0) {
+               int j;
+               for (j = 0; j < i; j++) {
+                       struct task *t = &wns[j].task;
+                       assert(t->error < 0);
+                       if (t->error != -E_WRITE_COMMON_EOF
+                                       && t->error != -E_BTR_EOF) {
+                               PARA_ERROR_LOG("%s: %s\n", t->status,
+                                       para_strerror(-t->error));
+                               if (ret >= 0)
+                                       ret = t->error;
+                       }
+               }
+       }
        for (i--; i >= 0; i--) {
                struct writer_node *wn = wns + i;
                struct writer *w = writers + wn->writer_num;
 
                w->close(wn);
                btr_free_node(wn->btrn);
+               w->free_config(wn->conf);
                free(wn->conf);
        }
        free(wns);
@@ -236,8 +275,7 @@ out:
  */
 int main(int argc, char *argv[])
 {
-       int ret = -E_WRITE_SYNTAX;
-       static struct sched s;
+       int ret;
 
        writer_init();
        write_cmdline_parser(argc, argv, &conf);
@@ -245,7 +283,7 @@ int main(int argc, char *argv[])
        if (conf.help_given || conf.detailed_help_given)
                print_help_and_die();
 
-       ret = main_btr(&s);
+       ret = setup_and_schedule();
        if (ret < 0) {
                PARA_ERROR_LOG("%s\n", para_strerror(-ret));
                exit(EXIT_FAILURE);