From e77983d3c55a7822e2151dfd60d9a20ec2023c9f Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 8 Oct 2010 22:23:05 +0200 Subject: [PATCH 24/38] alsaloop: Fix command-line parsing and pollfd initialization Signed-off-by: Jaroslav Kysela --- alsaloop/alsaloop.c | 28 ++++++++++++++++++++-------- alsaloop/control.c | 4 ++++ alsaloop/pcmjob.c | 24 +++++++++++++----------- alsaloop/test.sh | 18 +++++++++++++++++- 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/alsaloop/alsaloop.c b/alsaloop/alsaloop.c index effa073..97b00d5 100644 --- a/alsaloop/alsaloop.c +++ b/alsaloop/alsaloop.c @@ -47,6 +47,8 @@ int daemonize = 0; int use_syslog = 0; struct loopback **loopbacks = NULL; int loopbacks_count = 0; +char **my_argv = NULL; +int my_argc = 0; static void my_exit(struct loopback_thread *thread, int exitcode) { @@ -575,9 +577,6 @@ static int parse_config_file(const char *file, snd_output_t *output) int argc, c, err = 0; char **argv; - argv = malloc(sizeof(char *) * MAX_ARGS); - if (argv == NULL) - return -ENOMEM; fp = fopen(file, "r"); if (fp == NULL) { logit(LOG_CRIT, "Unable to open file '%s': %s\n", file, strerror(errno)); @@ -587,8 +586,13 @@ static int parse_config_file(const char *file, snd_output_t *output) if (fgets(line, sizeof(line)-1, fp) == NULL) break; line[sizeof(line)-1] = '\0'; + my_argv = realloc(my_argv, my_argc + MAX_ARGS * sizeof(char *)); + if (my_argv == NULL) + return -ENOMEM; + argv = my_argv + my_argc; argc = 0; argv[argc++] = strdup(""); + my_argc++; str = line; while (*str) { ptr = word; @@ -607,25 +611,30 @@ static int parse_config_file(const char *file, snd_output_t *output) *ptr++ = *str++; } if (ptr != word) { + if (*(ptr-1) == '\n') + ptr--; *ptr = '\0'; + if (argc >= MAX_ARGS) { + logit(LOG_CRIT, "Too many arguments."); + goto __error; + } argv[argc++] = strdup(word); + my_argc++; } } /* erase runtime variables for getopt */ optarg = NULL; optind = opterr = 1; - optopt = 63; + optopt = '?'; err = parse_config(argc, argv, output); __next: - while (argc > 0) - free(argv[--argc]); if (err < 0) break; err = 0; } + __error: fclose(fp); - free(argv); return err; } @@ -656,7 +665,7 @@ static void thread_job1(void *_data) pfds_count += thread->loopbacks[i]->pollfd_count; } pfds = calloc(pfds_count, sizeof(struct pollfd)); - if (pfds == NULL) { + if (pfds == NULL || pfds_count <= 0) { logit(LOG_CRIT, "Poll FDs allocation failed.\n"); my_exit(thread, EXIT_FAILURE); } @@ -723,6 +732,9 @@ int main(int argc, char *argv[]) logit(LOG_CRIT, "Unable to parse arguments or configuration...\n"); exit(EXIT_FAILURE); } + while (my_argc > 0) + free(my_argv[--my_argc]); + free(my_argv); if (loopbacks_count <= 0) { logit(LOG_CRIT, "No loopback defined...\n"); diff --git a/alsaloop/control.c b/alsaloop/control.c index 967f1e9..8383d79 100644 --- a/alsaloop/control.c +++ b/alsaloop/control.c @@ -164,6 +164,10 @@ static int control_init1(struct loopback_handle *lhandle, snd_ctl_elem_info_set_id(ctl->info, ctl->id); snd_ctl_elem_value_set_id(ctl->value, ctl->id); + if (lhandle->ctl == NULL) { + logit(LOG_WARNING, "Unable to read control info for '%s'\n", id_str(ctl->id)); + return -EIO; + } err = snd_ctl_elem_info(lhandle->ctl, ctl->info); if (err < 0) { logit(LOG_WARNING, "Unable to read control info '%s': %s\n", id_str(ctl->id), snd_strerror(err)); diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c index 5c2fed0..df835f0 100644 --- a/alsaloop/pcmjob.c +++ b/alsaloop/pcmjob.c @@ -1195,6 +1195,16 @@ int pcmjob_start(struct loopback *loop) snd_pcm_uframes_t count; int err; + loop->pollfd_count = loop->play->ctl_pollfd_count + + loop->capt->ctl_pollfd_count; + if ((err = snd_pcm_poll_descriptors_count(loop->play->handle)) < 0) + goto __error; + loop->play->pollfd_count = err; + loop->pollfd_count += err; + if ((err = snd_pcm_poll_descriptors_count(loop->capt->handle)) < 0) + goto __error; + loop->capt->pollfd_count = err; + loop->pollfd_count += err; if (loop->slave == SLAVE_TYPE_ON) { err = get_active(loop->capt); if (err < 0) @@ -1214,8 +1224,6 @@ int pcmjob_start(struct loopback *loop) goto __error; loop->play->channels = loop->capt->channels = err; } - loop->pollfd_count = loop->play->ctl_pollfd_count + - loop->capt->ctl_pollfd_count; loop->reinit = 0; loop->use_samplerate = 0; loop->latency = loop->latency_req; @@ -1258,14 +1266,6 @@ int pcmjob_start(struct loopback *loop) if (loop->capt->rate_req != loop->capt->rate) loop->use_samplerate = 1; } - if ((err = snd_pcm_poll_descriptors_count(loop->play->handle)) < 0) - goto __error; - loop->play->pollfd_count = err; - loop->pollfd_count += err; - if ((err = snd_pcm_poll_descriptors_count(loop->capt->handle)) < 0) - goto __error; - loop->capt->pollfd_count = err; - loop->pollfd_count += err; #ifdef USE_SAMPLERATE if (loop->sync == SYNC_TYPE_SAMPLERATE) loop->use_samplerate = 1; @@ -1463,9 +1463,11 @@ static int handle_ctl_events(struct loopback_handle *lhandle, if (lhandle == lhandle->loopback->play) goto __ctl_check; if (verbose > 6) - snd_output_printf(lhandle->loopback->output, "ctl event!!!! %s\n", snd_ctl_event_elem_get_name(ev)); + snd_output_printf(lhandle->loopback->output, "%s: ctl event!!!! %s\n", lhandle->id, snd_ctl_event_elem_get_name(ev)); if (ctl_event_check(lhandle->ctl_active, ev)) { err = get_active(lhandle); + if (verbose > 7) + snd_output_printf(lhandle->loopback->output, "%s: ctl event active %i\n", lhandle->id, err); if (err != lhandle->loopback->running) goto __restart; } else if (ctl_event_check(lhandle->ctl_format, ev)) { diff --git a/alsaloop/test.sh b/alsaloop/test.sh index 13a5ba7..91f4cbc 100755 --- a/alsaloop/test.sh +++ b/alsaloop/test.sh @@ -2,6 +2,7 @@ #DBG="gdb --args " #DBG="strace" +#DBG="valgrind --leak-check=full" CFGFILE="/tmp/alsaloop.test.cfg" test1() { @@ -35,7 +36,8 @@ cat > $CFGFILE < $CFGFILE <