diff options
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 \ @@ -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) |