Skip to content

Commit

Permalink
snd_dlopen: implement the relocatable version for glibc
Browse files Browse the repository at this point in the history
BugLink: #34
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
  • Loading branch information
perexg committed Jun 4, 2020
1 parent b2a4272 commit 33089f3
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
1 change: 1 addition & 0 deletions include/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ extern struct snd_dlsym_link *snd_dlsym_start;
/** \brief Returns the version of a dynamic symbol as a string. */
#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_dlsym(void *handle, const char *name, const char *version);
int snd_dlclose(void *handle);
Expand Down
10 changes: 7 additions & 3 deletions modules/mixer/simple/python.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "Python.h"
#include <stddef.h>
#include <limits.h>
#include "config.h"
#include "asoundlib.h"
#include "mixer_abst.h"
Expand All @@ -36,7 +37,7 @@ struct python_priv {
PyObject *py_mixer;
};

#define SCRIPT ALSA_PLUGIN_DIR "/smixer/python/main.py"
#define SCRIPT "smixer/python/main.py"

struct pymelem {
PyObject_HEAD
Expand Down Expand Up @@ -1110,6 +1111,7 @@ int alsa_mixer_simple_finit(snd_mixer_class_t *class,
FILE *fp;
const char *file;
PyObject *obj, *py_mod;
char path[PATH_MAX];

priv = calloc(1, sizeof(*priv));
if (priv == NULL)
Expand All @@ -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);

file = getenv("ALSA_MIXER_SIMPLE_MPYTHON");
if (file == NULL)
file = SCRIPT;
if (file == NULL) {
snd_dlpath(path, sizeof(path), SCRIPT);
file = path;
}

fp = fopen(file, "r");
if (fp == NULL) {
Expand Down
48 changes: 42 additions & 6 deletions src/dlmisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,50 @@
#ifdef HAVE_LIBPTHREAD
#include <pthread.h>
#endif
#include <limits.h>

#ifndef DOC_HIDDEN
#ifndef PIC
struct snd_dlsym_link *snd_dlsym_start = NULL;
#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.
* \param name name of the library, similar to \c dlopen.
Expand Down Expand Up @@ -79,14 +116,12 @@ void *snd_dlopen(const char *name, int mode, char *errbuf, size_t errbuflen)
* via ld.so.conf.
*/
void *handle = NULL;
char *filename = NULL;
const char *filename = NULL;
char path[PATH_MAX];

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);
if (snd_dlpath(path, sizeof(path), name) == 0) {
filename = name;
handle = dlopen(filename, mode);
if (!handle) {
/* if the filename exists and cannot be opened */
Expand All @@ -97,6 +132,7 @@ void *snd_dlopen(const char *name, int mode, char *errbuf, size_t errbuflen)
}
}
if (!handle) {
filename = name;
handle = dlopen(name, mode);
if (!handle)
goto errpath;
Expand Down

0 comments on commit 33089f3

Please sign in to comment.