[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