diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 74d1d1a..17ffb12 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -2042,6 +2042,19 @@ static const char *const build_in_pcms[] = { NULL }; + +// helper funcion used below +int file_exists(const char * filename) +{ + FILE * file; + if (file = fopen(filename, "r")) + { + fclose(file); + return 1; + } + return 0; +} + static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name, snd_config_t *pcm_root, snd_config_t *pcm_conf, snd_pcm_stream_t stream, int mode) @@ -2141,8 +2154,38 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name, err = -ENOMEM; goto _err; } - lib = buf1; sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str); + if (!file_exists(buf1)){ + // try to locate plugin in one of ALSA_PLUGIN_DIRS which is colon separated list of paths + char * pdirs = getenv("ALSA_PLUGIN_DIRS"); + + if (pdirs){ // env var set? + char * saveptr; + while (1) { + char * dir_tok = strtok_r(pdirs, "::::", &saveptr); // "::::" to work around bug in glibc and -O2 ? ":" seems to cause a segfault + if (dir_tok == NULL) + break; + char * so_file = malloc(strlen(str) + strlen(dir_tok) + 32); + if (so_file == NULL) { + err = -ENOMEM; + goto _err; + } + + sprintf(so_file, "%s/libasound_module_pcm_%s.so", dir_tok, str); + + if (file_exists(so_file)){ + + free(buf1); + buf1 = so_file; + break; + } else { + free (so_file); + } + pdirs = NULL; + } + } + } + lib = buf1; } } #ifndef PIC diff --git a/src/control/control.c b/src/control/control.c index c090797..137fe57 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -854,8 +854,38 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name, err = -ENOMEM; goto _err; } + sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str); + if (!file_exists(buf1)){ + // try to locate plugin in one of ALSA_PLUGIN_DIRS which is colon separated list of paths + char * pdirs = getenv("ALSA_PLUGIN_DIRS"); + + if (pdirs){ // env var set? + char * saveptr; + while (1) { + char * dir_tok = strtok_r(pdirs, "::::", &saveptr); // "::::" to work around bug in glibc and -O2 ? ":" seems to cause a segfault + if (dir_tok == NULL) + break; + char * so_file = malloc(strlen(str) + strlen(dir_tok) + 32); + if (so_file == NULL) { + err = -ENOMEM; + goto _err; + } + + sprintf(so_file, "%s/libasound_module_ctl_%s.so", dir_tok, str); + + if (file_exists(so_file)){ + + free(buf1); + buf1 = so_file; + break; + } else { + free (so_file); + } + pdirs = NULL; + } + } + } lib = buf1; - sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str); } } #ifndef PIC diff --git a/src/dlmisc.c b/src/dlmisc.c index 8c8f3ff7..274d4b84 100644 --- a/src/dlmisc.c +++ b/src/dlmisc.c @@ -82,19 +82,52 @@ void *snd_dlopen(const char *name, int mode, char *errbuf, size_t errbuflen) char *filename = NULL; if (name && name[0] != '/') { - filename = alloca(sizeof(ALSA_PLUGIN_DIR) + 1 + strlen(name) + 1); - if (filename) { - strcpy(filename, ALSA_PLUGIN_DIR); - strcat(filename, "/"); - strcat(filename, name); - handle = dlopen(filename, mode); - if (!handle) { - /* if the filename exists and cannot be opened */ - /* return immediately */ - if (access(filename, X_OK) == 0) - goto errpath; + // 'name' is the full library.so name, e.g. libasound_module_conf_pulse.so + fprintf(stderr, "XXX name is %s\n", name); + char * plugindirs = getenv("ALSA_PLUGIN_DIRS"); + fprintf(stderr, "XXX plugindirs are %s\n" ,plugindirs); + if (plugindirs) { + char * saveptr; + while (1) { + // See comment in src/control/control.c about "::::" + char * dir_tok = strtok_r(plugindirs, "::::", &saveptr); + if (dir_tok == NULL) + break; + fprintf(stderr, "XXX dir token is %s\n" ,dir_tok); + char * so_file = malloc(strlen(name) + strlen(dir_tok) + 32); + sprintf(so_file, "%s/%s" ,dir_tok, name); + // TODO Check if so_file == NULL here + if (file_exists(so_file)) { + fprintf(stderr, "XXX Found the library %s\n" ,so_file); + handle = dlopen(filename, mode); + if (!handle) { + /* if the filename exists and cannot be opened */ + /* return immediately */ + if (access(filename, X_OK) == 0) + goto errpath; + } + break; + } else { + fprintf(stderr, "XXX Did not find the library %s\n" ,so_file); + break; + } } } +// Cut here: +// filename = alloca(sizeof(ALSA_PLUGIN_DIR) + 1 + strlen(name) + 1); +// if (filename) { +// strcpy(filename, ALSA_PLUGIN_DIR); +// strcat(filename, "/"); +// strcat(filename, name); +// handle = dlopen(filename, mode); +// if (!handle) { +// /* if the filename exists and cannot be opened */ +// /* return immediately */ +// if (access(filename, X_OK) == 0) +// goto errpath; +// } +// } +// ... to here. } if (!handle) { handle = dlopen(name, mode); @@ -104,6 +137,7 @@ void *snd_dlopen(const char *name, int mode, char *errbuf, size_t errbuflen) return handle; errpath: if (errbuf) + fprintf(stderr, "XXX couldn't find your thing!\n"); snprintf(errbuf, errbuflen, "%s: %s", filename, dlerror()); #endif return NULL;