]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Return from filter_setup() so callers can reset the terminal.
authorAndre Noll <maan@tuebingen.mpg.de>
Wed, 23 Nov 2022 18:21:25 +0000 (19:21 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Fri, 19 Apr 2024 18:41:23 +0000 (20:41 +0200)
This function of filter_common.c calls exit(3) on errors. This is OK
for para_filter and para_audiod, but not for para_play because there
the function is called after readline has initialized the terminal for
its own use. If the function calls exit(3), the terminal settings are
not reset as they should have been. This can be observed for example
on the attempt to open an mp3 file with an para_play executable that
lacks mp3 support.

This commit changes the function to return an error code instead and
deals with the fallout in the three callers. Although play.c already
had error checking for calls to filter_setup(), it still needs a minor
tweak because we now have to deal with the fact that the filter and
writer node don't exist in eof_cleanup().

audiod.c
filter.c
filter_common.c
play.c

index 7c223995a9a29cec3c8e8ae5497c3be58655f63c..bb5dd7037c61bc77d737422b45c77607527950a3 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -828,11 +828,14 @@ static int parse_stream_command(const char *txt, const char **cmd)
 static int add_filter(int format, const char *cmdline)
 {
        struct audio_format_info *a = &afi[format];
-       int filter_num, nf = a->num_filters;
+       int ret, filter_num, nf = a->num_filters;
        void *cfg;
        struct lls_parse_result *flpr;
 
-       filter_num = filter_setup(cmdline, &cfg, &flpr);
+       ret = filter_setup(cmdline, &cfg, &flpr);
+       if (ret < 0)
+               return ret;
+       filter_num = ret;
        a->filter_lpr = arr_realloc(a->filter_lpr, nf + 1, sizeof(flpr));
        a->filter_conf = arr_realloc(a->filter_conf, nf + 1, sizeof(void *));
        a->filter_nums = arr_realloc(a->filter_nums, nf + 1, sizeof(unsigned));
index 722cb16fb35bfaec09bbaca046ebf62931df8036..50447ec0cd2a165c974e4fea68e288e98a1713e3 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -128,7 +128,10 @@ int main(int argc, char *argv[])
                struct task_info ti;
 
                fn = fns[i] = zalloc(sizeof(*fn));
-               fn->filter_num = filter_setup(fa, &fn->conf, &filter_lpr);
+               ret = filter_setup(fa, &fn->conf, &filter_lpr);
+               if (ret < 0)
+                       goto teardown;
+               fn->filter_num = ret;
                name = filter_name(fn->filter_num);
                fn->lpr = filter_lpr;
                PARA_DEBUG_LOG("filter #%d: %s\n", i, name);
@@ -153,6 +156,7 @@ int main(int argc, char *argv[])
        btr_log_tree(sit->btrn, LL_INFO);
        ret = schedule(&s);
        sched_shutdown(&s);
+teardown:
        for (i--; i >= 0; i--) {
                struct filter_node *fn = fns[i];
 
index f48e457005ca3510fb51d5e5f95405af15d927c1..7966b806f0745bfc6d35b630693ef31e285ac3a8 100644 (file)
@@ -67,11 +67,11 @@ const char *filter_name(int filter_num)
  * filter, optionally followed by options for this filter. If yes, call the
  * command line parser of that filter and its ->setup method.
  *
- * \return This function either succeeds or does not return. On success, the
- * number of the filter is returned and conf is initialized to point to the
- * filter configuration as returned by the filter's ->setup() method, if any.
- * Moreover, *lprp is initialized to contain the parsed command line options.
- * On errors, the function calls exit(EXIT_FAILURE).
+ * \return On success, the number of the filter is returned and conf is
+ * initialized to point to the filter configuration as returned by the filter's
+ * ->setup() method, if any.  Moreover, *lprp is initialized to contain the
+ * parsed command line options. On errors a negative paraslash error code is
+ * returned.
  */
 int filter_setup(const char *fa, void **conf, struct lls_parse_result **lprp)
 {
@@ -80,9 +80,10 @@ int filter_setup(const char *fa, void **conf, struct lls_parse_result **lprp)
        const struct lls_command *cmd;
        const struct filter *f;
 
+       *lprp = NULL;
        ret = create_argv(fa, " \t\n", &argv);
        if (ret < 0)
-               goto fail;
+               return ret;
        argc = ret;
        ret = lls(lls_lookup_subcmd(argv[0], filter_cmd_suite, &errctx));
        if (ret < 0)
@@ -105,12 +106,10 @@ free_argv:
        free_argv(argv);
        if (ret >= 0)
                return ret;
-fail:
        if (errctx)
                PARA_ERROR_LOG("%s\n", errctx);
        free(errctx);
-       PARA_EMERG_LOG("%s\n", para_strerror(-ret));
-       exit(EXIT_FAILURE);
+       return ret;
 }
 
 /**
diff --git a/play.c b/play.c
index e6510b03b15843b0ebd01c6d022a6200a7a71fb7..4f734a3f729c526b8b319edbf2a477c636e2abe6 100644 (file)
--- a/play.c
+++ b/play.c
@@ -223,7 +223,7 @@ static int get_playback_error(void)
        int err;
 
        if (!pt->wn.task)
-               return 0;
+               return 1;
        err = task_status(pt->wn.task);
        if (err >= 0)
                return 0;
@@ -254,7 +254,7 @@ static int eof_cleanup(void)
 
        decoder = filter_get(pt->fn.filter_num);
        task_reap(&pt->fn.task);
-       if (decoder->close)
+       if (decoder && decoder->close)
                decoder->close(&pt->fn);
        btr_remove_node(&pt->fn.btrn);
        lls_free_parse_result(pt->fn.lpr, FILTER_CMD(pt->fn.filter_num));