Toggle diff (197 lines)
diff --git a/gnu/local.mk b/gnu/local.mk
index 39267f2765..78e63fe7ff 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -741,6 +741,7 @@ dist_patch_DATA = \
%D%/packages/patches/akonadi-not-relocatable.patch \
%D%/packages/patches/akonadi-timestamps.patch \
%D%/packages/patches/allegro-mesa-18.2.5-and-later.patch \
+ %D%/packages/patches/alsa-lib-plugin-dirs.patch \
%D%/packages/patches/amule-crypto-6.patch \
%D%/packages/patches/anki-mpv-args.patch \
%D%/packages/patches/antiword-CVE-2014-8123.patch \
diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm
index 4fb29b8490..8ea5bb909a 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -1771,6 +1771,7 @@ intercept and print the system calls executed by the program.")
(define-public alsa-lib
(package
(name "alsa-lib")
+ (replacement alsa-lib/fixed)
(version "1.2.2")
(source (origin
(method url-fetch)
@@ -1792,6 +1793,15 @@ intercept and print the system calls executed by the program.")
MIDI functionality to the Linux-based operating system.")
(license license:lgpl2.1+)))
+(define alsa-lib/fixed
+ (package
+ (inherit alsa-lib)
+ (source (origin
+ (inherit (package-source alsa-lib))
+ (patches (append
+ (origin-patches (package-source alsa-lib))
+ (search-patches "alsa-lib-plugin-dirs.patch")))))))
+
(define-public alsa-utils
(package
(name "alsa-utils")
diff --git a/gnu/packages/patches/alsa-lib-plugin-dirs.patch b/gnu/packages/patches/alsa-lib-plugin-dirs.patch
new file mode 100644
index 0000000000..0d6cb57f4e
--- /dev/null
+++ b/gnu/packages/patches/alsa-lib-plugin-dirs.patch
@@ -0,0 +1,149 @@
+From 5bc1a490fa68187bce15eb9e8305b88ff6fbdbe5 Mon Sep 17 00:00:00 2001
+From: Leo Famulari <leo@famulari.name>
+Date: Mon, 27 Apr 2020 13:09:54 -0400
+Subject: [PATCH] Search for plugins in $GUIX_ALSA_PLUGIN_DIRS.
+
+* src/control/control.c (snd_ctl_open_conf): If ALSA plugins cannot be found in
+the default locations, look in the directories in $GUIX_ALSA_PLUGIN_DIRS.
+* src/dlmisc.c (snd_dlopen): Likewise.
+* src/pcm/pcm.c (snd_pcm_open_conf): Likewise.
+---
+ src/control/control.c | 35 ++++++++++++++++++++++++++++++++++-
+ src/dlmisc.c | 26 +++++++++++++++++++++-----
+ src/pcm/pcm.c | 35 ++++++++++++++++++++++++++++++++++-
+ 3 files changed, 89 insertions(+), 7 deletions(-)
+
+diff --git a/src/control/control.c b/src/control/control.c
+index 27f42135..108a560b 100644
+--- a/src/control/control.c
++++ b/src/control/control.c
+@@ -1342,8 +1342,41 @@ 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 (access(buf1, F_OK) != 0) {
++ const char *plugindirs = getenv("GUIX_ALSA_PLUGIN_DIRS");
++
++ if (plugindirs) {
++ char *plugindirs_copy = alloca(strlen(plugindirs) + 1);
++ if (plugindirs_copy == NULL) {
++ err = -ENOMEM;
++ goto _err;
++ }
++ strcpy(plugindirs_copy, plugindirs);
++ char *saveptr;
++ while (1) {
++ char *dir_tok = strtok_r(plugindirs_copy, ":", &saveptr);
++ if (dir_tok == NULL)
++ break;
++ char *so_file = malloc(strlen(dir_tok) + 1 + strlen(str) + 32);
++ if (so_file == NULL) {
++ err = -ENOMEM;
++ goto _err;
++ }
++
++ sprintf(so_file, "%s/libasound_module_ctl_%s.so", dir_tok, str);
++
++ if (access(so_file, F_OK) == 0) {
++ buf1 = so_file;
++ break;
++ } else {
++ free (so_file);
++ }
++ plugindirs_copy = 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..b115447c 100644
+--- a/src/dlmisc.c
++++ b/src/dlmisc.c
+@@ -82,11 +82,27 @@ 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);
++ const char *plugindirs = getenv("GUIX_ALSA_PLUGIN_DIRS");
++ if (plugindirs) {
++ char *plugindirs_copy = alloca(strlen(plugindirs) + 1);
++ if (plugindirs_copy == NULL)
++ goto errpath;
++ strcpy(plugindirs_copy, plugindirs);
++ char *saveptr;
++ while (1) {
++ char *dir_tok = strtok_r(plugindirs_copy, ":", &saveptr);
++ if (dir_tok == NULL)
++ break;
++ char *sofilename = malloc(strlen(dir_tok) + 1 + strlen(name) + 1);
++ sprintf(sofilename, "%s/%s" ,dir_tok, name);
++ if (access(sofilename, F_OK) == 0) {
++ filename = sofilename;
++ break;
++ } else {
++ free (sofilename);
++ }
++ plugindirs_copy = NULL;
++ }
+ handle = dlopen(filename, mode);
+ if (!handle) {
+ /* if the filename exists and cannot be opened */
+diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
+index 1064044c..90ba00ac 100644
+--- a/src/pcm/pcm.c
++++ b/src/pcm/pcm.c
+@@ -2578,8 +2578,41 @@ 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 (access(buf1, F_OK) != 0) {
++ const char *plugindirs = getenv("GUIX_ALSA_PLUGIN_DIRS");
++
++ if (plugindirs) {
++ char *plugindirs_copy = alloca(strlen(plugindirs) + 1);
++ if (plugindirs_copy == NULL) {
++ err = -ENOMEM;
++ goto _err;
++ }
++ strcpy(plugindirs_copy, plugindirs);
++ char *saveptr;
++ while (1) {
++ char *dir_tok = strtok_r(plugindirs_copy, ":", &saveptr);
++ if (dir_tok == NULL)
++ break;
++ char *so_file = malloc(strlen(dir_tok) + 1 + strlen(str) + 32);
++ if (so_file == NULL) {
++ err = -ENOMEM;
++ goto _err;
++ }
++
++ sprintf(so_file, "%s/libasound_module_pcm_%s.so", dir_tok, str);
++
++ if (access(so_file, F_OK) == 0) {
++ buf1 = so_file;
++ break;
++ } else {
++ free (so_file);
++ }
++ plugindirs_copy = NULL;
++ }
++ }
++ }
++ lib = buf1;
+ }
+ }
+ #ifndef PIC
+--
+2.26.2
+
--
2.26.2