aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/conf.h5
-rw-r--r--include/control.h3
-rw-r--r--include/global.h6
-rw-r--r--include/hwdep.h3
-rw-r--r--include/local.h2
-rw-r--r--include/pcm.h3
-rw-r--r--include/rawmidi.h3
-rw-r--r--include/seq.h3
-rw-r--r--include/timer.h5
-rw-r--r--src/Makefile.am2
-rw-r--r--src/conf.c18
-rw-r--r--src/confmisc.c100
-rw-r--r--src/control/control.c10
-rw-r--r--src/control/control_hw.c1
-rw-r--r--src/control/control_shm.c1
-rw-r--r--src/dlmisc.c56
-rw-r--r--src/hwdep/hwdep.c10
-rw-r--r--src/hwdep/hwdep_hw.c1
-rw-r--r--src/pcm/pcm.c25
-rw-r--r--src/pcm/pcm_adpcm.c1
-rw-r--r--src/pcm/pcm_alaw.c1
-rw-r--r--src/pcm/pcm_copy.c1
-rw-r--r--src/pcm/pcm_file.c1
-rw-r--r--src/pcm/pcm_hooks.c3
-rw-r--r--src/pcm/pcm_hw.c1
-rw-r--r--src/pcm/pcm_linear.c1
-rw-r--r--src/pcm/pcm_meter.c3
-rw-r--r--src/pcm/pcm_mulaw.c1
-rw-r--r--src/pcm/pcm_multi.c1
-rw-r--r--src/pcm/pcm_null.c1
-rw-r--r--src/pcm/pcm_plug.c1
-rw-r--r--src/pcm/pcm_rate.c1
-rw-r--r--src/pcm/pcm_route.c1
-rw-r--r--src/pcm/pcm_share.c1
-rw-r--r--src/pcm/pcm_shm.c1
-rw-r--r--src/rawmidi/rawmidi.c10
-rw-r--r--src/rawmidi/rawmidi_hw.c1
-rw-r--r--src/seq/seq.c10
-rw-r--r--src/seq/seq_hw.c1
-rw-r--r--src/timer/timer.c10
-rw-r--r--src/timer/timer_hw.c1
-rw-r--r--src/timer/timer_query.c10
-rw-r--r--src/timer/timer_query_hw.c1
43 files changed, 184 insertions, 137 deletions
diff --git a/include/conf.h b/include/conf.h
index eea2958d..825925c5 100644
--- a/include/conf.h
+++ b/include/conf.h
@@ -4,6 +4,11 @@
* \{
*/
+/** dlsym version for config evaluate callback */
+#define SND_CONFIG_DLSYM_VERSION_EVALUATE _dlsym_config_evaluate_001
+/** dlsym version for config hook callback */
+#define SND_CONFIG_DLSYM_VERSION_HOOK _dlsym_config_hook_001
+
/** Config node type */
typedef enum _snd_config_type {
/** Integer number */
diff --git a/include/control.h b/include/control.h
index 05b38f66..3574b4ab 100644
--- a/include/control.h
+++ b/include/control.h
@@ -11,6 +11,9 @@
* \{
*/
+/** dlsym version for interface entry callback */
+#define SND_CONTROL_DLSYM_VERSION _dlsym_control_001
+
/** IEC958 structure */
typedef struct sndrv_aes_iec958 snd_aes_iec958_t;
diff --git a/include/global.h b/include/global.h
index 13cf47c6..a17f9639 100644
--- a/include/global.h
+++ b/include/global.h
@@ -14,6 +14,12 @@
/** \} */
+#define __SND_DLSYM_VERSION(name, version) _ ## name ## version
+#define SND_DLSYM_BUILD_VERSION(name, version) char __SND_DLSYM_VERSION(name, version)
+#define SND_DLSYM_VERSION(version) __STRING(version)
+
+int snd_dlsym_verify(void *handle, const char *name, const char *version);
+
/** Async notification client handler */
typedef struct _snd_async_handler snd_async_handler_t;
diff --git a/include/hwdep.h b/include/hwdep.h
index 3636edac..48bf4be2 100644
--- a/include/hwdep.h
+++ b/include/hwdep.h
@@ -11,6 +11,9 @@
* \{
*/
+/** dlsym version for interface entry callback */
+#define SND_HWDEP_DLSYM_VERSION _dlsym_hwdep_001
+
/** HwDep information container */
typedef struct _snd_hwdep_info snd_hwdep_info_t;
diff --git a/include/local.h b/include/local.h
index b3f5f5c6..db15b0da 100644
--- a/include/local.h
+++ b/include/local.h
@@ -24,8 +24,6 @@
#include "config.h"
-#define ALSA_LIB "libasound.so"
-
#define _snd_config_iterator list_head
#define _snd_interval sndrv_interval
#define _snd_pcm_info sndrv_pcm_info
diff --git a/include/pcm.h b/include/pcm.h
index 6df82ae4..68996d7b 100644
--- a/include/pcm.h
+++ b/include/pcm.h
@@ -11,6 +11,9 @@
* \{
*/
+/** dlsym version for interface entry callback */
+#define SND_PCM_DLSYM_VERSION _dlsym_pcm_001
+
/** PCM generic info container */
typedef struct _snd_pcm_info snd_pcm_info_t;
/** PCM hardware configuration space container */
diff --git a/include/rawmidi.h b/include/rawmidi.h
index b982cd66..e7e6f8a3 100644
--- a/include/rawmidi.h
+++ b/include/rawmidi.h
@@ -11,6 +11,9 @@
* \{
*/
+/** dlsym version for interface entry callback */
+#define SND_RAWMIDI_DLSYM_VERSION _dlsym_rawmidi_001
+
/** RawMidi information container */
typedef struct _snd_rawmidi_info snd_rawmidi_info_t;
/** RawMidi settings container */
diff --git a/include/seq.h b/include/seq.h
index 75736b7e..60a35f55 100644
--- a/include/seq.h
+++ b/include/seq.h
@@ -9,6 +9,9 @@ extern "C" {
* \{
*/
+/** dlsym version for interface entry callback */
+#define SND_SEQ_DLSYM_VERSION _dlsym_seq_001
+
/** Sequencer handle */
typedef struct _snd_seq snd_seq_t;
diff --git a/include/timer.h b/include/timer.h
index 8c1cb22d..8a25e146 100644
--- a/include/timer.h
+++ b/include/timer.h
@@ -11,6 +11,11 @@
* \{
*/
+/** dlsym version for interface entry callback */
+#define SND_TIMER_DLSYM_VERSION _dlsym_timer_001
+/** dlsym version for interface entry callback */
+#define SND_TIMER_QUERY_DLSYM_VERSION _dlsym_timer_query_001
+
/** timer identification structure */
typedef struct _snd_timer_id snd_timer_id_t;
/** timer info structure */
diff --git a/src/Makefile.am b/src/Makefile.am
index 6409d970..7aefd18c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,7 +2,7 @@ SUBDIRS=control mixer pcm rawmidi timer hwdep seq instr compat conf
COMPATNUM=@LIBTOOL_VERSION_INFO@
lib_LTLIBRARIES = libasound.la
-libasound_la_SOURCES = conf.c confmisc.c input.c output.c async.c error.c
+libasound_la_SOURCES = conf.c confmisc.c input.c output.c async.c error.c dlmisc.c
libasound_la_LIBADD = control/libcontrol.la mixer/libmixer.la pcm/libpcm.la \
rawmidi/librawmidi.la timer/libtimer.la \
hwdep/libhwdep.la seq/libseq.la instr/libinstr.la \
diff --git a/src/conf.c b/src/conf.c
index ff542821..5c2a0cc4 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -1801,18 +1801,18 @@ static int snd_config_hooks_call(snd_config_t *root, snd_config_t *config, void
buf[len-1] = '\0';
func_name = buf;
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
+ if ((err = snd_dlsym_verify(h, func_name, SND_DLSYM_VERSION(SND_CONFIG_DLSYM_VERSION_HOOK))) < 0)
+ goto _err;
func = h ? dlsym(h, func_name) : NULL;
err = 0;
if (!h) {
SNDERR("Cannot open shared library %s", lib);
- return -ENOENT;
+ err = -ENOENT;
} else if (!func) {
SNDERR("symbol %s is not defined inside %s", func_name, lib);
dlclose(h);
- return -ENXIO;
+ err = -ENXIO;
}
_err:
if (func_conf)
@@ -1877,6 +1877,7 @@ static int snd_config_hooks(snd_config_t *config, void *private_data)
* \param private_data Private data
* \return zero if success, otherwise a negative error code
*/
+SND_DLSYM_BUILD_VERSION(snd_config_hook_load, SND_CONFIG_DLSYM_VERSION_HOOK);
int snd_config_hook_load(snd_config_t *root, snd_config_t *config, snd_config_t **dst, void *private_data)
{
snd_config_t *n, *res = NULL;
@@ -2011,6 +2012,7 @@ int snd_determine_driver(int card, char **driver);
* \param private_data Private data
* \return zero if success, otherwise a negative error code
*/
+SND_DLSYM_BUILD_VERSION(snd_config_hook_load_for_all_cards, SND_CONFIG_DLSYM_VERSION_HOOK);
int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config, snd_config_t **dst, void *private_data ATTRIBUTE_UNUSED)
{
int card = -1, err;
@@ -2504,10 +2506,12 @@ static int _snd_config_evaluate(snd_config_t *src,
buf[len-1] = '\0';
func_name = buf;
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
- func = h ? dlsym(h, func_name) : NULL;
+ if (h) {
+ if ((err = snd_dlsym_verify(h, func_name, SND_DLSYM_VERSION(SND_CONFIG_DLSYM_VERSION_EVALUATE))) < 0)
+ goto _err;
+ func = dlsym(h, func_name);
+ }
err = 0;
if (!h) {
SNDERR("Cannot open shared library %s", lib);
diff --git a/src/confmisc.c b/src/confmisc.c
index 516b2463..12104ecd 100644
--- a/src/confmisc.c
+++ b/src/confmisc.c
@@ -139,96 +139,11 @@ int snd_config_get_ctl_iface(snd_config_t *conf)
return err;
}
-/**
- * \brief Refer the configuration block to another
- * \param dst new configuration block (if *dst != root -> dst needs to be deleted)
- * \param name the identifier of new configuration block
- * \param root the root of all configurations
- * \param config redirect configuration
- */
-int snd_config_refer_load(snd_config_t **dst,
- char **name,
- snd_config_t *root,
- snd_config_t *config)
-{
- int err;
- snd_config_t *result, *c;
- char *rname;
-
- assert(dst);
- assert(name);
- assert(root);
- assert(config);
- if (snd_config_get_type(config) == SND_CONFIG_TYPE_STRING) {
- const char *str;
- snd_config_get_string(config, &str);
- *name = strdup(str);
- if (*name == NULL)
- return -ENOMEM;
- *dst = root;
- return 0;
- }
- if (snd_config_get_type(config) != SND_CONFIG_TYPE_COMPOUND)
- return -EINVAL;
- result = root;
- rname = NULL;
- if (snd_config_search(config, "file", &c) >= 0) {
- snd_config_t *rconfig;
- const char *filename;
- snd_input_t *input;
- err = snd_config_copy(&rconfig, root);
- if (err < 0)
- return err;
- if (snd_config_get_type(c) == SND_CONFIG_TYPE_STRING) {
- snd_config_get_string(c, &filename);
- } else {
- err = -EINVAL;
- __filename_error:
- snd_config_delete(rconfig);
- return err;
- }
- err = snd_input_stdio_open(&input, filename, "r");
- if (err < 0) {
- SNDERR("Unable to open filename %s: %s", filename, snd_strerror(err));
- goto __filename_error;
- }
- err = snd_config_load(rconfig, input);
- if (err < 0) {
- snd_input_close(input);
- goto __filename_error;
- }
- snd_input_close(input);
- result = rconfig;
- }
- if (snd_config_search(config, "name", &c) >= 0) {
- const char *ptr;
- if ((err = snd_config_get_string(c, &ptr)) < 0)
- goto __error;
- rname = strdup(ptr);
- if (rname == NULL) {
- err = -ENOMEM;
- goto __error;
- }
- }
- if (rname == NULL) {
- err = -EINVAL;
- goto __error;
- }
- *dst = result;
- *name = rname;
- return 0;
- __error:
- if (rname)
- free(rname);
- if (result != root)
- snd_config_delete(result);
- return err;
-}
-
/*
* Helper functions for the configuration file
*/
+SND_DLSYM_BUILD_VERSION(snd_func_getenv, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_getenv(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data)
{
snd_config_t *n, *d;
@@ -307,6 +222,7 @@ int snd_func_getenv(snd_config_t **dst, snd_config_t *root, snd_config_t *src, v
return err;
}
+SND_DLSYM_BUILD_VERSION(snd_func_igetenv, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_igetenv(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data)
{
snd_config_t *d;
@@ -331,8 +247,8 @@ int snd_func_igetenv(snd_config_t **dst, snd_config_t *root, snd_config_t *src,
_end:
return err;
}
-
-
+
+SND_DLSYM_BUILD_VERSION(snd_func_concat, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_concat(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data)
{
snd_config_t *n;
@@ -397,6 +313,7 @@ int snd_func_concat(snd_config_t **dst, snd_config_t *root, snd_config_t *src, v
return err;
}
+SND_DLSYM_BUILD_VERSION(snd_func_datadir, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_datadir(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED,
snd_config_t *src, void *private_data ATTRIBUTE_UNUSED)
{
@@ -428,6 +345,7 @@ static int string_from_integer(char **dst, long v)
}
#endif
+SND_DLSYM_BUILD_VERSION(snd_func_private_string, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_private_string(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *src, void *private_data)
{
int err;
@@ -472,6 +390,7 @@ int snd_determine_driver(int card, char **driver)
return err;
}
+SND_DLSYM_BUILD_VERSION(snd_func_private_card_strtype, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_private_card_strtype(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *src, void *private_data)
{
char *driver;
@@ -486,6 +405,7 @@ int snd_func_private_card_strtype(snd_config_t **dst, snd_config_t *root ATTRIBU
return err;
}
+SND_DLSYM_BUILD_VERSION(snd_func_card_strtype, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_card_strtype(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data)
{
snd_config_t *n;
@@ -518,6 +438,7 @@ int snd_func_card_strtype(snd_config_t **dst, snd_config_t *root, snd_config_t *
return snd_func_private_card_strtype(dst, root, src, (void *)v);
}
+SND_DLSYM_BUILD_VERSION(snd_func_card_id, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_card_id(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data)
{
snd_config_t *n;
@@ -568,6 +489,7 @@ int snd_func_card_id(snd_config_t **dst, snd_config_t *root, snd_config_t *src,
return err;
}
+SND_DLSYM_BUILD_VERSION(snd_func_pcm_id, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_pcm_id(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data)
{
snd_config_t *n;
@@ -640,6 +562,7 @@ int snd_func_pcm_id(snd_config_t **dst, snd_config_t *root, snd_config_t *src, v
return err;
}
+SND_DLSYM_BUILD_VERSION(snd_func_private_pcm_subdevice, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_private_pcm_subdevice(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *src, void *private_data)
{
char *res = NULL;
@@ -664,6 +587,7 @@ int snd_func_private_pcm_subdevice(snd_config_t **dst, snd_config_t *root ATTRIB
return err;
}
+SND_DLSYM_BUILD_VERSION(snd_func_refer, SND_CONFIG_DLSYM_VERSION_EVALUATE);
int snd_func_refer(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data)
{
snd_config_t *n;
diff --git a/src/control/control.c b/src/control/control.c
index 5f4abc8f..77f6bc99 100644
--- a/src/control/control.c
+++ b/src/control/control.c
@@ -502,10 +502,14 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
open_name = buf;
snprintf(buf, sizeof(buf), "_snd_ctl_%s_open", str);
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
- open_func = h ? dlsym(h, open_name) : NULL;
+ if (h) {
+ if ((err = snd_dlsym_verify(h, open_name, SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION))) < 0) {
+ dlclose(h);
+ goto _err;
+ }
+ open_func = dlsym(h, open_name);
+ }
err = 0;
if (!h) {
SNDERR("Cannot open shared library %s", lib);
diff --git a/src/control/control_hw.c b/src/control/control_hw.c
index 5374c9a2..e880142e 100644
--- a/src/control/control_hw.c
+++ b/src/control/control_hw.c
@@ -318,6 +318,7 @@ int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode)
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_ctl_hw_open, SND_CONTROL_DLSYM_VERSION);
int _snd_ctl_hw_open(snd_ctl_t **handlep, char *name, snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf)
{
snd_config_iterator_t i, next;
diff --git a/src/control/control_shm.c b/src/control/control_shm.c
index f04834f6..4e7329e8 100644
--- a/src/control/control_shm.c
+++ b/src/control/control_shm.c
@@ -525,6 +525,7 @@ int snd_ctl_shm_open(snd_ctl_t **handlep, const char *name, const char *sockname
return result;
}
+SND_DLSYM_BUILD_VERSION(_snd_ctl_shm_open, SND_CONTROL_DLSYM_VERSION);
int _snd_ctl_shm_open(snd_ctl_t **handlep, char *name, snd_config_t *root, snd_config_t *conf, int mode)
{
snd_config_iterator_t i, next;
diff --git a/src/dlmisc.c b/src/dlmisc.c
new file mode 100644
index 00000000..2d5ce752
--- /dev/null
+++ b/src/dlmisc.c
@@ -0,0 +1,56 @@
+/**
+ * \file dlmisc.c
+ * \brief dynamic loader helpers
+ * \author Jaroslav Kysela <perex@suse.cz>
+ * \date 2001
+ *
+ * Dynamic loader helpers
+ */
+/*
+ * Dynamic loader helpers
+ * Copyright (c) 2000 by Jaroslav Kysela <perex@suse.cz>
+ *
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <dlfcn.h>
+#include "local.h"
+
+/**
+ * \brief Verify dynamically loaded symbol
+ * \param handle dlopen handle
+ * \param name name of symbol
+ * \param version version of symbol
+ * \return zero is success, otherwise a negative error code
+ */
+int snd_dlsym_verify(void *handle, const char *name, const char *version)
+{
+ int res;
+ char *vname;
+
+ if (handle == NULL)
+ return -EINVAL;
+ vname = alloca(1 + strlen(name) + strlen(version) + 1);
+ vname[0] = '_';
+ strcpy(vname + 1, name);
+ strcat(vname, version);
+ res = dlsym(handle, vname) == NULL ? -ENOENT : 0;
+ printf("dlsym verify: %i, vname = '%s'\n", res, vname);
+ if (res < 0)
+ SNDERR("unable to verify version for symbol %s", name);
+ return res;
+}
diff --git a/src/hwdep/hwdep.c b/src/hwdep/hwdep.c
index c3621e05..ac76f469 100644
--- a/src/hwdep/hwdep.c
+++ b/src/hwdep/hwdep.c
@@ -102,10 +102,14 @@ static int snd_hwdep_open_conf(snd_hwdep_t **hwdep,
open_name = buf;
snprintf(buf, sizeof(buf), "_snd_hwdep_%s_open", str);
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
- open_func = h ? dlsym(h, open_name) : NULL;
+ if (h) {
+ if ((err = snd_dlsym_verify(h, open_name, SND_DLSYM_VERSION(SND_HWDEP_DLSYM_VERSION))) < 0) {
+ dlclose(h);
+ goto _err;
+ }
+ open_func = dlsym(h, open_name);
+ }
if (!h) {
SNDERR("Cannot open shared library %s", lib);
err = -ENOENT;
diff --git a/src/hwdep/hwdep_hw.c b/src/hwdep/hwdep_hw.c
index fbbfa7dc..2a436171 100644
--- a/src/hwdep/hwdep_hw.c
+++ b/src/hwdep/hwdep_hw.c
@@ -137,6 +137,7 @@ int snd_hwdep_hw_open(snd_hwdep_t **handle, const char *name, int card, int devi
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_hwdep_hw_open, SND_HWDEP_DLSYM_VERSION);
int _snd_hwdep_hw_open(snd_hwdep_t **hwdep, char *name,
snd_config_t *root ATTRIBUTE_UNUSED,
snd_config_t *conf, int mode)
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index e6d98916..2a53b234 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -1056,10 +1056,14 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
open_name = buf;
snprintf(buf, sizeof(buf), "_snd_pcm_%s_open", str);
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
- open_func = h ? dlsym(h, open_name) : NULL;
+ if (h) {
+ if ((err = snd_dlsym_verify(h, open_name, SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION))) < 0) {
+ dlclose(h);
+ goto _err;
+ }
+ open_func = dlsym(h, open_name);
+ }
err = 0;
if (!h) {
SNDERR("Cannot open shared library %s", lib);
@@ -1079,25 +1083,12 @@ static int snd_pcm_open_noupdate(snd_pcm_t **pcmp, snd_config_t *root,
const char *name, snd_pcm_stream_t stream, int mode)
{
int err;
- snd_config_t *pcm_conf, *n;
+ snd_config_t *pcm_conf;
err = snd_config_search_definition(root, "pcm", name, &pcm_conf);
if (err < 0) {
SNDERR("Unknown PCM %s", name);
return err;
}
- if (snd_config_search(pcm_conf, "refer", &n) >= 0) {
- snd_config_t *refer;
- char *new_name;
- err = snd_config_refer_load(&refer, &new_name, root, n);
- if (err < 0) {
- SNDERR("Unable to load refered block in PCM %s: %s", name, snd_strerror(err));
- return err;
- }
- err = snd_pcm_open_noupdate(pcmp, refer, new_name, stream, mode);
- if (refer != root)
- snd_config_delete(refer);
- return err;
- }
err = snd_pcm_open_conf(pcmp, name, root, pcm_conf, stream, mode);
snd_config_delete(pcm_conf);
return err;
diff --git a/src/pcm/pcm_adpcm.c b/src/pcm/pcm_adpcm.c
index b8f06112..2b43154d 100644
--- a/src/pcm/pcm_adpcm.c
+++ b/src/pcm/pcm_adpcm.c
@@ -541,6 +541,7 @@ int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_adpcm_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_alaw.c b/src/pcm/pcm_alaw.c
index 230bf947..dd1e9d9b 100644
--- a/src/pcm/pcm_alaw.c
+++ b/src/pcm/pcm_alaw.c
@@ -414,6 +414,7 @@ int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sform
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_alaw_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_copy.c b/src/pcm/pcm_copy.c
index 8c6b4863..796b7633 100644
--- a/src/pcm/pcm_copy.c
+++ b/src/pcm/pcm_copy.c
@@ -184,6 +184,7 @@ int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_copy_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
index 66971124..cbd0fdb1 100644
--- a/src/pcm/pcm_file.c
+++ b/src/pcm/pcm_file.c
@@ -449,6 +449,7 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, const char *fname, int
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_file_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_hooks.c b/src/pcm/pcm_hooks.c
index 49a59c1d..98879465 100644
--- a/src/pcm/pcm_hooks.c
+++ b/src/pcm/pcm_hooks.c
@@ -394,8 +394,6 @@ static int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *root, snd_config_
install = buf;
snprintf(buf, sizeof(buf), "_snd_pcm_hook_%s_install", str);
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
install_func = h ? dlsym(h, install) : NULL;
err = 0;
@@ -425,6 +423,7 @@ static int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *root, snd_config_
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_hooks_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 327aad2a..adab12c5 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -640,6 +640,7 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, int card, int device, in
return ret;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_hw_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_linear.c b/src/pcm/pcm_linear.c
index 6bbe90fe..3b4a68dc 100644
--- a/src/pcm/pcm_linear.c
+++ b/src/pcm/pcm_linear.c
@@ -319,6 +319,7 @@ int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_linear_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_meter.c b/src/pcm/pcm_meter.c
index 0b1c49d9..01b2868c 100644
--- a/src/pcm/pcm_meter.c
+++ b/src/pcm/pcm_meter.c
@@ -704,8 +704,6 @@ static int snd_pcm_meter_add_scope_conf(snd_pcm_t *pcm, const char *name,
open_name = buf;
snprintf(buf, sizeof(buf), "_snd_pcm_scope_%s_open", str);
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
open_func = h ? dlsym(h, open_name) : NULL;
err = 0;
@@ -724,6 +722,7 @@ static int snd_pcm_meter_add_scope_conf(snd_pcm_t *pcm, const char *name,
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_meter_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_mulaw.c b/src/pcm/pcm_mulaw.c
index a8a32efa..620d7ac7 100644
--- a/src/pcm/pcm_mulaw.c
+++ b/src/pcm/pcm_mulaw.c
@@ -429,6 +429,7 @@ int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_mulaw_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c
index de59198b..a8a5003b 100644
--- a/src/pcm/pcm_multi.c
+++ b/src/pcm/pcm_multi.c
@@ -643,6 +643,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_multi_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_null.c b/src/pcm/pcm_null.c
index 0e6a3c63..6360be38 100644
--- a/src/pcm/pcm_null.c
+++ b/src/pcm/pcm_null.c
@@ -358,6 +358,7 @@ int snd_pcm_null_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t strea
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_null_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_null_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c
index 7463b600..1ee99496 100644
--- a/src/pcm/pcm_plug.c
+++ b/src/pcm/pcm_plug.c
@@ -771,6 +771,7 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
#define MAX_CHANNELS 64
+SND_DLSYM_BUILD_VERSION(_snd_pcm_plug_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
index fd8030c7..8aee1517 100644
--- a/src/pcm/pcm_rate.c
+++ b/src/pcm/pcm_rate.c
@@ -528,6 +528,7 @@ int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sform
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_rate_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c
index 776e1500..a229cb0c 100644
--- a/src/pcm/pcm_route.c
+++ b/src/pcm/pcm_route.c
@@ -833,6 +833,7 @@ int snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_entry_t *tt
#define MAX_CHANNELS 32
+SND_DLSYM_BUILD_VERSION(_snd_pcm_route_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c
index 529fad16..65fab30e 100644
--- a/src/pcm/pcm_share.c
+++ b/src/pcm/pcm_share.c
@@ -1359,6 +1359,7 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_share_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/pcm/pcm_shm.c b/src/pcm/pcm_shm.c
index bdba9215..0b1770c5 100644
--- a/src/pcm/pcm_shm.c
+++ b/src/pcm/pcm_shm.c
@@ -710,6 +710,7 @@ int is_local(struct hostent *hent)
return i < numreqs;
}
+SND_DLSYM_BUILD_VERSION(_snd_pcm_shm_open, SND_PCM_DLSYM_VERSION);
int _snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
diff --git a/src/rawmidi/rawmidi.c b/src/rawmidi/rawmidi.c
index 92fa1679..5718d96a 100644
--- a/src/rawmidi/rawmidi.c
+++ b/src/rawmidi/rawmidi.c
@@ -128,10 +128,14 @@ static int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp
open_name = buf;
snprintf(buf, sizeof(buf), "_snd_rawmidi_%s_open", str);
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
- open_func = h ? dlsym(h, open_name) : NULL;
+ if (h) {
+ if ((err = snd_dlsym_verify(h, open_name, SND_DLSYM_VERSION(SND_RAWMIDI_DLSYM_VERSION))) < 0) {
+ dlclose(h);
+ goto _err;
+ }
+ open_func = dlsym(h, open_name);
+ }
if (!h) {
SNDERR("Cannot open shared library %s", lib);
err = -ENOENT;
diff --git a/src/rawmidi/rawmidi_hw.c b/src/rawmidi/rawmidi_hw.c
index 49bb4fa4..b5103d68 100644
--- a/src/rawmidi/rawmidi_hw.c
+++ b/src/rawmidi/rawmidi_hw.c
@@ -302,6 +302,7 @@ int snd_rawmidi_hw_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
return -ENOMEM;
}
+SND_DLSYM_BUILD_VERSION(_snd_rawmidi_hw_open, SND_RAWMIDI_DLSYM_VERSION);
int _snd_rawmidi_hw_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
char *name, snd_config_t *root ATTRIBUTE_UNUSED,
snd_config_t *conf, int mode)
diff --git a/src/seq/seq.c b/src/seq/seq.c
index 1596b32f..1fa300a3 100644
--- a/src/seq/seq.c
+++ b/src/seq/seq.c
@@ -129,10 +129,14 @@ static int snd_seq_open_conf(snd_seq_t **seqp, const char *name,
open_name = buf;
snprintf(buf, sizeof(buf), "_snd_seq_%s_open", str);
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
- open_func = h ? dlsym(h, open_name) : NULL;
+ if (h) {
+ if ((err = snd_dlsym_verify(h, open_name, SND_DLSYM_VERSION(SND_SEQ_DLSYM_VERSION))) < 0) {
+ dlclose(h);
+ goto _err;
+ }
+ open_func = dlsym(h, open_name);
+ }
err = 0;
if (!h) {
SNDERR("Cannot open shared library %s", lib);
diff --git a/src/seq/seq_hw.c b/src/seq/seq_hw.c
index 6a239bfc..a6637665 100644
--- a/src/seq/seq_hw.c
+++ b/src/seq/seq_hw.c
@@ -503,6 +503,7 @@ int snd_seq_hw_open(snd_seq_t **handle, const char *name, int streams, int mode)
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_seq_hw_open, SND_SEQ_DLSYM_VERSION);
int _snd_seq_hw_open(snd_seq_t **handlep, char *name,
snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf,
int streams, int mode)
diff --git a/src/timer/timer.c b/src/timer/timer.c
index f5078436..cdf41a08 100644
--- a/src/timer/timer.c
+++ b/src/timer/timer.c
@@ -101,10 +101,14 @@ static int snd_timer_open_conf(snd_timer_t **timer,
open_name = buf;
snprintf(buf, sizeof(buf), "_snd_timer_%s_open", str);
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
- open_func = h ? dlsym(h, open_name) : NULL;
+ if (h) {
+ if ((err = snd_dlsym_verify(h, open_name, SND_DLSYM_VERSION(SND_TIMER_DLSYM_VERSION))) < 0) {
+ dlclose(h);
+ goto _err;
+ }
+ open_func = dlsym(h, open_name);
+ }
if (!h) {
SNDERR("Cannot open shared library %s", lib);
err = -ENOENT;
diff --git a/src/timer/timer_hw.c b/src/timer/timer_hw.c
index bea25196..dd1f20d7 100644
--- a/src/timer/timer_hw.c
+++ b/src/timer/timer_hw.c
@@ -200,6 +200,7 @@ int snd_timer_hw_open(snd_timer_t **handle, const char *name, int dev_class, int
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_timer_hw_open, SND_TIMER_DLSYM_VERSION);
int _snd_timer_hw_open(snd_timer_t **timer, char *name,
snd_config_t *root ATTRIBUTE_UNUSED,
snd_config_t *conf, int mode)
diff --git a/src/timer/timer_query.c b/src/timer/timer_query.c
index 1492e1ed..ebdd65c3 100644
--- a/src/timer/timer_query.c
+++ b/src/timer/timer_query.c
@@ -100,10 +100,14 @@ static int snd_timer_query_open_conf(snd_timer_query_t **timer,
open_name = buf;
snprintf(buf, sizeof(buf), "_snd_timer_query_%s_open", str);
}
- if (!lib)
- lib = ALSA_LIB;
h = dlopen(lib, RTLD_NOW);
- open_func = h ? dlsym(h, open_name) : NULL;
+ if (h) {
+ if ((err = snd_dlsym_verify(h, open_name, SND_DLSYM_VERSION(SND_TIMER_QUERY_DLSYM_VERSION))) < 0) {
+ dlclose(h);
+ goto _err;
+ }
+ open_func = dlsym(h, open_name);
+ }
if (!h) {
SNDERR("Cannot open shared library %s", lib);
err = -ENOENT;
diff --git a/src/timer/timer_query_hw.c b/src/timer/timer_query_hw.c
index 6d70a317..e63a4811 100644
--- a/src/timer/timer_query_hw.c
+++ b/src/timer/timer_query_hw.c
@@ -88,6 +88,7 @@ int snd_timer_query_hw_open(snd_timer_query_t **handle, const char *name, int mo
return 0;
}
+SND_DLSYM_BUILD_VERSION(_snd_timer_query_hw_open, SND_TIMER_QUERY_DLSYM_VERSION);
int _snd_timer_query_hw_open(snd_timer_query_t **timer, char *name,
snd_config_t *root ATTRIBUTE_UNUSED,
snd_config_t *conf, int mode)