mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2026-03-16 05:33:43 -04:00
snd_dlopen: implement the relocatable version for glibc
BugLink: https://github.com/alsa-project/alsa-lib/issues/34 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
b2a4272ecb
commit
33089f30a3
3 changed files with 50 additions and 9 deletions
|
|
@ -97,6 +97,7 @@ extern struct snd_dlsym_link *snd_dlsym_start;
|
||||||
/** \brief Returns the version of a dynamic symbol as a string. */
|
/** \brief Returns the version of a dynamic symbol as a string. */
|
||||||
#define SND_DLSYM_VERSION(version) __STRING(version)
|
#define SND_DLSYM_VERSION(version) __STRING(version)
|
||||||
|
|
||||||
|
int snd_dlpath(char *path, size_t path_len, const char *name);
|
||||||
void *snd_dlopen(const char *file, int mode, char *errbuf, size_t errbuflen);
|
void *snd_dlopen(const char *file, int mode, char *errbuf, size_t errbuflen);
|
||||||
void *snd_dlsym(void *handle, const char *name, const char *version);
|
void *snd_dlsym(void *handle, const char *name, const char *version);
|
||||||
int snd_dlclose(void *handle);
|
int snd_dlclose(void *handle);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "asoundlib.h"
|
#include "asoundlib.h"
|
||||||
#include "mixer_abst.h"
|
#include "mixer_abst.h"
|
||||||
|
|
@ -36,7 +37,7 @@ struct python_priv {
|
||||||
PyObject *py_mixer;
|
PyObject *py_mixer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCRIPT ALSA_PLUGIN_DIR "/smixer/python/main.py"
|
#define SCRIPT "smixer/python/main.py"
|
||||||
|
|
||||||
struct pymelem {
|
struct pymelem {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
@ -1110,6 +1111,7 @@ int alsa_mixer_simple_finit(snd_mixer_class_t *class,
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
const char *file;
|
const char *file;
|
||||||
PyObject *obj, *py_mod;
|
PyObject *obj, *py_mod;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
priv = calloc(1, sizeof(*priv));
|
priv = calloc(1, sizeof(*priv));
|
||||||
if (priv == NULL)
|
if (priv == NULL)
|
||||||
|
|
@ -1119,8 +1121,10 @@ int alsa_mixer_simple_finit(snd_mixer_class_t *class,
|
||||||
snd_mixer_sbasic_set_private_free(class, alsa_mixer_simple_free);
|
snd_mixer_sbasic_set_private_free(class, alsa_mixer_simple_free);
|
||||||
|
|
||||||
file = getenv("ALSA_MIXER_SIMPLE_MPYTHON");
|
file = getenv("ALSA_MIXER_SIMPLE_MPYTHON");
|
||||||
if (file == NULL)
|
if (file == NULL) {
|
||||||
file = SCRIPT;
|
snd_dlpath(path, sizeof(path), SCRIPT);
|
||||||
|
file = path;
|
||||||
|
}
|
||||||
|
|
||||||
fp = fopen(file, "r");
|
fp = fopen(file, "r");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
|
|
|
||||||
48
src/dlmisc.c
48
src/dlmisc.c
|
|
@ -32,6 +32,7 @@
|
||||||
#ifdef HAVE_LIBPTHREAD
|
#ifdef HAVE_LIBPTHREAD
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#ifndef DOC_HIDDEN
|
#ifndef DOC_HIDDEN
|
||||||
#ifndef PIC
|
#ifndef PIC
|
||||||
|
|
@ -39,6 +40,42 @@ struct snd_dlsym_link *snd_dlsym_start = NULL;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* \brief Compose the dynamic path
|
||||||
|
* \param path Returned path (string)
|
||||||
|
* \param path_len Returned path max size (with trailing zero)
|
||||||
|
* \param name Plugin name (relative)
|
||||||
|
* \return Zero on success, otherwise a negative error code
|
||||||
|
*/
|
||||||
|
int snd_dlpath(char *path, size_t path_len, const char *name)
|
||||||
|
{
|
||||||
|
static const char *origin_dir = NULL;
|
||||||
|
#ifdef HAVE_LIBDL
|
||||||
|
#ifdef __GLIBC__
|
||||||
|
static int plugin_dir_set = 0;
|
||||||
|
if (!plugin_dir_set) {
|
||||||
|
struct link_map *links;
|
||||||
|
Dl_info info;
|
||||||
|
char origin[PATH_MAX];
|
||||||
|
if (dladdr1(&snd_dlpath, &info, (void**)&links, RTLD_DL_LINKMAP) == 0)
|
||||||
|
links = NULL;
|
||||||
|
if (links != NULL && dlinfo(links, RTLD_DI_ORIGIN, origin) == 0) {
|
||||||
|
snprintf(path, path_len, "%s/alsa-lib", origin);
|
||||||
|
if (access(path, X_OK) == 0)
|
||||||
|
origin_dir = origin;
|
||||||
|
}
|
||||||
|
plugin_dir_set = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
if (origin_dir)
|
||||||
|
snprintf(path, path_len, "%s/alsa-lib/%s", origin_dir, name);
|
||||||
|
else
|
||||||
|
snprintf(path, path_len, "%s/%s", ALSA_PLUGIN_DIR, name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Opens a dynamic library - ALSA wrapper for \c dlopen.
|
* \brief Opens a dynamic library - ALSA wrapper for \c dlopen.
|
||||||
* \param name name of the library, similar to \c dlopen.
|
* \param name name of the library, similar to \c dlopen.
|
||||||
|
|
@ -79,14 +116,12 @@ void *snd_dlopen(const char *name, int mode, char *errbuf, size_t errbuflen)
|
||||||
* via ld.so.conf.
|
* via ld.so.conf.
|
||||||
*/
|
*/
|
||||||
void *handle = NULL;
|
void *handle = NULL;
|
||||||
char *filename = NULL;
|
const char *filename = NULL;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
if (name && name[0] != '/') {
|
if (name && name[0] != '/') {
|
||||||
filename = alloca(sizeof(ALSA_PLUGIN_DIR) + 1 + strlen(name) + 1);
|
if (snd_dlpath(path, sizeof(path), name) == 0) {
|
||||||
if (filename) {
|
filename = name;
|
||||||
strcpy(filename, ALSA_PLUGIN_DIR);
|
|
||||||
strcat(filename, "/");
|
|
||||||
strcat(filename, name);
|
|
||||||
handle = dlopen(filename, mode);
|
handle = dlopen(filename, mode);
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
/* if the filename exists and cannot be opened */
|
/* if the filename exists and cannot be opened */
|
||||||
|
|
@ -97,6 +132,7 @@ void *snd_dlopen(const char *name, int mode, char *errbuf, size_t errbuflen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
|
filename = name;
|
||||||
handle = dlopen(name, mode);
|
handle = dlopen(name, mode);
|
||||||
if (!handle)
|
if (!handle)
|
||||||
goto errpath;
|
goto errpath;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue