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));
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);
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];
* 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)
{
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)
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;
}
/**
int err;
if (!pt->wn.task)
- return 0;
+ return 1;
err = task_status(pt->wn.task);
if (err >= 0)
return 0;
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));