SHA256
1
0
forked from pool/alsa-utils
alsa-utils/0024-alsaloop-Fix-command-line-parsing-and-pollfd-initial.patch

228 lines
7.2 KiB
Diff
Raw Normal View History

From e77983d3c55a7822e2151dfd60d9a20ec2023c9f Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
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 <perex@perex.cz>
---
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("<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");
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 <<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
--
1.7.3.1