[alsa-devel] [PATCH] conf: Allow for a directory to be given as a config file.
Takashi Iwai
tiwai at suse.de
Fri Sep 16 08:51:12 CEST 2011
At Tue, 13 Sep 2011 22:04:00 +0100,
gmane at colin.guthr.ie wrote:
>
> From: Colin Guthrie <colin at mageia.org>
>
> When this is done, *.conf files can be placed in that directory and they
> will be processed by as if they were included directly.
>
> A directory (typically /usr/share/alsa/alsa.conf.d/) has been
> added into the distribution.
In this code, the error behavior looks inconsistent.
In a config file case (no directory), the opening failure gives only
the error message but it continues. In the case of directory, both
the open-error and the parse-error are treated as the fatal error.
OK, it's basically a mistake in the original code -- the open-error
should be handled as a fatal error more consistently. But, still,
the old error code was overridden by the new entry, so the error in
the middle of the file-entry loop is ignored. That looks no good.
And, the code becomes with too deep indentation. This indicates
already something wrong. Split a new function to handle the directory
case. And create a small function to handle below code:
err = snd_input_stdio_open(&in, filename, "r");
if (err >= 0) {
err = snd_config_load(root, in);
snd_input_close(in);
if (err < 0)
SNDERR("%s may be old or corrupted: consider to remove or fix it", filename);
} else
SNDERR("cannot access file %s", filename);
return err;
and use it from both a single file and files-in-directory cases.
thanks,
Takashi
> ---
> configure.in | 3 +-
> src/conf.c | 75 ++++++++++++++++++++++++++++++++++----
> src/conf/Makefile.am | 2 +-
> src/conf/alsa.conf | 7 ++++
> src/conf/alsa.conf.d/Makefile.am | 8 ++++
> src/conf/alsa.conf.d/README | 2 +
> 6 files changed, 87 insertions(+), 10 deletions(-)
> create mode 100644 src/conf/alsa.conf.d/Makefile.am
> create mode 100644 src/conf/alsa.conf.d/README
>
> diff --git a/configure.in b/configure.in
> index 7ee0ccc..13e38b8 100644
> --- a/configure.in
> +++ b/configure.in
> @@ -616,7 +616,8 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \
> src/pcm/Makefile src/pcm/scopes/Makefile \
> src/rawmidi/Makefile src/timer/Makefile \
> src/hwdep/Makefile src/seq/Makefile src/ucm/Makefile \
> - src/compat/Makefile src/alisp/Makefile src/conf/Makefile \
> + src/compat/Makefile src/alisp/Makefile \
> + src/conf/Makefile src/conf/alsa.conf.d/Makefile \
> src/conf/cards/Makefile \
> src/conf/pcm/Makefile \
> modules/Makefile modules/mixer/Makefile modules/mixer/simple/Makefile \
> diff --git a/src/conf.c b/src/conf.c
> index ddefff6..9b1169b 100644
> --- a/src/conf.c
> +++ b/src/conf.c
> @@ -417,6 +417,7 @@ beginning:</P>
> #include <stdarg.h>
> #include <limits.h>
> #include <sys/stat.h>
> +#include <dirent.h>
> #include <locale.h>
> #include "local.h"
> #ifdef HAVE_LIBPTHREAD
> @@ -3373,6 +3374,25 @@ static int snd_config_hooks(snd_config_t *config, snd_config_t *private_data)
> return err;
> }
>
> +static int config_filename_filter(const struct dirent *dirent)
> +{
> + size_t flen;
> +
> + if (dirent == NULL)
> + return 0;
> + if (dirent->d_type == DT_DIR)
> + return 0;
> +
> + flen = strlen(dirent->d_name);
> + if (flen <= 5)
> + return 0;
> +
> + if (strncmp(&dirent->d_name[flen-5], ".conf", 5) == 0)
> + return 1;
> +
> + return 0;
> +}
> +
> /**
> * \brief Loads and parses the given configurations files.
> * \param[in] root Handle to the root configuration node.
> @@ -3458,18 +3478,57 @@ int snd_config_hook_load(snd_config_t *root, snd_config_t *config, snd_config_t
> } while (hit);
> for (idx = 0; idx < fi_count; idx++) {
> snd_input_t *in;
> + struct stat st;
> if (!errors && access(fi[idx].name, R_OK) < 0)
> continue;
> - err = snd_input_stdio_open(&in, fi[idx].name, "r");
> - if (err >= 0) {
> - err = snd_config_load(root, in);
> - snd_input_close(in);
> - if (err < 0) {
> - SNDERR("%s may be old or corrupted: consider to remove or fix it", fi[idx].name);
> - goto _err;
> + if (stat(fi[idx].name, &st) < 0) {
> + SNDERR("cannot stat file/directory %s", fi[idx].name);
> + continue;
> + }
> + if (S_ISDIR(st.st_mode)) {
> + struct dirent **namelist;
> + int n;
> +
> + n = scandir(fi[idx].name, &namelist, config_filename_filter, versionsort);
> + if (n > 0) {
> + int j;
> + err = 0;
> + for (j = 0; j < n; ++j) {
> + if (err >= 0) {
> + int sl = strlen(fi[idx].name) + strlen(namelist[j]->d_name) + 2;
> + char *filename = malloc(sl);
> + snprintf(filename, sl, "%s/%s", fi[idx].name, namelist[j]->d_name);
> + filename[sl-1] = '\0';
> +
> + err = snd_input_stdio_open(&in, filename, "r");
> + if (err >= 0) {
> + err = snd_config_load(root, in);
> + snd_input_close(in);
> + if (err < 0)
> + SNDERR("%s may be old or corrupted: consider to remove or fix it", filename);
> + } else {
> + SNDERR("cannot access file %s", filename);
> + }
> + free(filename);
> + }
> + free(namelist[j]);
> + }
> + free(namelist);
> + if (err < 0)
> + goto _err;
> }
> } else {
> - SNDERR("cannot access file %s", fi[idx].name);
> + err = snd_input_stdio_open(&in, fi[idx].name, "r");
> + if (err >= 0) {
> + err = snd_config_load(root, in);
> + snd_input_close(in);
> + if (err < 0) {
> + SNDERR("%s may be old or corrupted: consider to remove or fix it", fi[idx].name);
> + goto _err;
> + }
> + } else {
> + SNDERR("cannot access file %s", fi[idx].name);
> + }
> }
> }
> *dst = NULL;
> diff --git a/src/conf/Makefile.am b/src/conf/Makefile.am
> index 2e5d0bf..456454f 100644
> --- a/src/conf/Makefile.am
> +++ b/src/conf/Makefile.am
> @@ -1,4 +1,4 @@
> -SUBDIRS=cards pcm
> +SUBDIRS=cards pcm alsa.conf.d
>
> cfg_files = alsa.conf
> if BUILD_ALISP
> diff --git a/src/conf/alsa.conf b/src/conf/alsa.conf
> index a33c24e..bc91df3 100644
> --- a/src/conf/alsa.conf
> +++ b/src/conf/alsa.conf
> @@ -8,6 +8,13 @@
> {
> func load
> files [
> + {
> + @func concat
> + strings [
> + { @func datadir }
> + "/alsa.conf.d/"
> + ]
> + }
> "/etc/asound.conf"
> "~/.asoundrc"
> ]
> diff --git a/src/conf/alsa.conf.d/Makefile.am b/src/conf/alsa.conf.d/Makefile.am
> new file mode 100644
> index 0000000..c91661e
> --- /dev/null
> +++ b/src/conf/alsa.conf.d/Makefile.am
> @@ -0,0 +1,8 @@
> +alsaconfigdir = @ALSA_CONFIG_DIR@
> +alsadir = $(alsaconfigdir)/alsa.conf.d
> +cfg_files = README
> +
> +alsa_DATA = $(cfg_files)
> +
> +EXTRA_DIST = \
> + $(cfg_files)
> diff --git a/src/conf/alsa.conf.d/README b/src/conf/alsa.conf.d/README
> new file mode 100644
> index 0000000..9997884
> --- /dev/null
> +++ b/src/conf/alsa.conf.d/README
> @@ -0,0 +1,2 @@
> +You can place files named *.conf in this folder and they will be processed
> +when initialising alsa-lib.
> --
> 1.7.6
>
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
More information about the Alsa-devel
mailing list