alsaloop: Fix command-line parsing and pollfd initialization

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2010-10-08 22:23:05 +02:00
parent 147a1cc75c
commit e77983d3c5
4 changed files with 54 additions and 20 deletions

View file

@ -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("<prog>");
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");

View file

@ -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));

View file

@ -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)) {

View file

@ -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 <<EOF
-C hw:1,0,0 -P plug:dmix:0 --tlatency 50000 --thread 0 \
--mixer "name='Master Playback Volume'@name='Master Playback Volume'" \
--mixer "name='Master Playback Switch'@name='Master Playback Switch'" \
--mixer "name='PCM Playback Volume'"
--mixer "name='PCM Playback Volume'" \
--ossmixer "name=Master@VOLUME"
-C hw:1,0,1 -P plug:dmix:0 --tlatency 50000 --thread 1
-C hw:1,0,2 -P plug:dmix:0 --tlatency 50000 --thread 2
-C hw:1,0,3 -P plug:dmix:0 --tlatency 50000 --thread 3
@ -56,10 +58,24 @@ test4() {
--mixer "name='PCM Playback Volume'"
}
test5() {
echo "TEST5"
cat > $CFGFILE <<EOF
-C hw:1,0,0 -P plughw:0,0 --tlatency 50000 --thread 1 \
--mixer "name='Master Playback Volume'@name='Master Playback Volume'" \
--mixer "name='Master Playback Switch'@name='Master Playback Switch'" \
--mixer "name='PCM Playback Volume'" \
--ossmixer "name=Master@VOLUME"
-C hw:1,0,1 -P plughw:0,1 --tlatency 50000 --thread 2
EOF
$DBG ./alsaloop --config $CFGFILE
}
case "$1" in
test1) test1 ;;
test2) test2 ;;
test3) test3 ;;
test4) test4 ;;
test5) test5 ;;
*) test1 ;;
esac