summary refs log blame commit diff
path: root/pkgs/os-specific/linux/alsa-lib/alsa-plugin-conf-multilib.patch
blob: b17df9a492e5bf862ce37a48ad3717925176287d (plain) (tree)







































































































































































































































                                                                                                       
diff --git a/src/control/control.c b/src/control/control.c
index d66ed75..42cecad 100644
--- a/src/control/control.c
+++ b/src/control/control.c
@@ -838,6 +838,10 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
 #ifndef PIC
 	extern void *snd_control_open_symbols(void);
 #endif
+
+	snd_config_t *libs = NULL;
+	const char *libs_lib = NULL;
+
 	if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND) {
 		if (name)
 			SNDERR("Invalid type for CTL %s definition", name);
@@ -879,6 +883,19 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
 					SNDERR("Invalid type for %s", id);
 					goto _err;
 				}
+
+				continue;
+			}
+			// Handle an array of extra libs.
+			if (strcmp(id, "libs") == 0) {
+				if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
+					SNDERR("Invalid type for libs definition in CTL %s definition",
+						str);
+					goto _err;
+				}
+
+				libs = n;
+
 				continue;
 			}
 			if (strcmp(id, "open") == 0) {
@@ -903,7 +920,62 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
 		open_name = buf;
 		sprintf(buf, "_snd_ctl_%s_open", str);
 	}
-	if (!lib) {
+
+#ifndef PIC
+	snd_control_open_symbols();
+#endif
+
+	// Normal alsa behaviour when there is no libs array.
+	if (!libs) {
+		if (lib) {
+			open_func = snd_dlobj_cache_get(lib, open_name,
+				SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
+		}
+	}
+	// Handle libs array.
+	// Suppresses error messages if any function is loaded successfully.
+	else {
+		if (lib) {
+			open_func = snd_dlobj_cache_get(lib, open_name,
+				SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 0);
+		}
+
+		if (!open_func) {
+			snd_config_for_each(i, next, libs) {
+				snd_config_t *n = snd_config_iterator_entry(i);
+
+				err = snd_config_get_string(n, &libs_lib);
+				if (err < 0) {
+					SNDERR("Invalid entry in CTL %s libs definition", str);
+					goto _err;
+				}
+
+				if (!open_func) {
+					open_func = snd_dlobj_cache_get(libs_lib, open_name,
+						SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 0);
+				}
+			}
+		}
+
+		// Print error messages.
+		if (!open_func) {
+			if (lib) {
+				SNDERR("Either %s cannot be opened or %s was not defined inside",
+					lib, open_name);
+			}
+
+			snd_config_for_each(i, next, libs) {
+				snd_config_t *n = snd_config_iterator_entry(i);
+
+				snd_config_get_string(n, &libs_lib);
+				SNDERR("Either %s cannot be opened or %s was not defined inside",
+					libs_lib, open_name);
+			}
+		}
+	}
+
+	// Look in ALSA_PLUGIN_DIR iff we found nowhere else to look.
+	if (!lib && (!libs || !libs_lib)) {
 		const char *const *build_in = build_in_ctls;
 		while (*build_in) {
 			if (!strcmp(*build_in, str))
@@ -919,12 +991,11 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
 			lib = buf1;
 			sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
 		}
-	}
-#ifndef PIC
-	snd_control_open_symbols();
-#endif
-	open_func = snd_dlobj_cache_get(lib, open_name,
+
+		open_func = snd_dlobj_cache_get(lib, open_name,
 			SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
+	}
+
 	if (open_func) {
 		err = open_func(ctlp, name, ctl_root, ctl_conf, mode);
 		if (err >= 0) {
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index 2e24338..7f489f4 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -2116,6 +2116,10 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
 #ifndef PIC
 	extern void *snd_pcm_open_symbols(void);
 #endif
+
+	snd_config_t *libs = NULL;
+	const char *libs_lib = NULL;
+
 	if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
 		char *val;
 		id = NULL;
@@ -2160,6 +2164,19 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
 					SNDERR("Invalid type for %s", id);
 					goto _err;
 				}
+
+				continue;
+			}
+			// Handle an array of extra libs.
+			if (strcmp(id, "libs") == 0) {
+				if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
+					SNDERR("Invalid type for libs definition in PCM %s definition",
+						str);
+					goto _err;
+				}
+
+				libs = n;
+
 				continue;
 			}
 			if (strcmp(id, "open") == 0) {
@@ -2184,7 +2201,62 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
 		open_name = buf;
 		sprintf(buf, "_snd_pcm_%s_open", str);
 	}
-	if (!lib) {
+
+#ifndef PIC
+	snd_pcm_open_symbols();	/* this call is for static linking only */
+#endif
+
+	// Normal alsa behaviour when there is no libs array.
+	if (!libs) {
+		if (lib) {
+			open_func = snd_dlobj_cache_get(lib, open_name,
+				SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
+		}
+	}
+	// Handle libs array.
+	// Suppresses error messages if any function is loaded successfully.
+	else {
+		if (lib) {
+			open_func = snd_dlobj_cache_get(lib, open_name,
+				SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 0);
+		}
+
+		if (!open_func) {
+			snd_config_for_each(i, next, libs) {
+				snd_config_t *n = snd_config_iterator_entry(i);
+
+				err = snd_config_get_string(n, &libs_lib);
+				if (err < 0) {
+					SNDERR("Invalid entry in PCM %s libs definition", str);
+					goto _err;
+				}
+
+				if (!open_func) {
+					open_func = snd_dlobj_cache_get(libs_lib, open_name,
+						SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 0);
+				}
+			}
+		}
+
+		// Print error messages.
+		if (!open_func) {
+			if (lib) {
+				SNDERR("Either %s cannot be opened or %s was not defined inside",
+					lib, open_name);
+			}
+
+			snd_config_for_each(i, next, libs) {
+				snd_config_t *n = snd_config_iterator_entry(i);
+
+				snd_config_get_string(n, &libs_lib);
+				SNDERR("Either %s cannot be opened or %s was not defined inside",
+					libs_lib, open_name);
+			}
+		}
+	}
+
+	// Look in ALSA_PLUGIN_DIR iff we found nowhere else to look.
+	if (!lib && (!libs || !libs_lib)) {
 		const char *const *build_in = build_in_pcms;
 		while (*build_in) {
 			if (!strcmp(*build_in, str))
@@ -2200,12 +2272,11 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
 			lib = buf1;
 			sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
 		}
-	}
-#ifndef PIC
-	snd_pcm_open_symbols();	/* this call is for static linking only */
-#endif
-	open_func = snd_dlobj_cache_get(lib, open_name,
+
+		open_func = snd_dlobj_cache_get(lib, open_name,
 			SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
+	}
+
 	if (open_func) {
 		err = open_func(pcmp, name, pcm_root, pcm_conf, stream, mode);
 		if (err >= 0) {