X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Flinux_specific.c;h=1644ce62133cdbeca5c8f16b97e3ace0b0df2cf4;hb=6bff1cc92a66ab1a73ba1fbf22523671bf5c8ce3;hp=79c880742b1dc4635f68a2899541e5b379cf5109;hpb=4d4f701e03e4b861f38249f001bec0ba7d286de1;p=vlc diff --git a/src/misc/linux_specific.c b/src/misc/linux_specific.c index 79c880742b..1644ce6213 100644 --- a/src/misc/linux_specific.c +++ b/src/misc/linux_specific.c @@ -28,49 +28,60 @@ #include #include "../libvlc.h" -#if 0 -#include -#include +static const char default_path[] = PKGLIBDIR; static void set_libvlc_path (void) { - static char libvlc_path[PATH_MAX]; - - assert (strlen (LIBDIR) < sizeof (libvlc_path)); - strcpy (libvlc_path, LIBDIR); /* fail safe */ - psz_vlcpath = libvlc_path; - /* Find the path to libvlc (i.e. ourselves) */ FILE *maps = fopen ("/proc/self/maps", "rt"); if (maps == NULL) - return; + goto error; + + char *line = NULL; + size_t linelen = 0; + uintptr_t needle = (uintptr_t)set_libvlc_path; for (;;) { - char buf[5000], *dir, *end; - - if (fgets (buf, sizeof (buf), maps) == NULL) + ssize_t len = getline (&line, &linelen, maps); + if (len == -1) break; - dir = strchr (buf, '/'); + void *start, *end; + if (sscanf (line, "%p-%p", &start, &end) < 2) + continue; + if (needle < (uintptr_t)start || (uintptr_t)end <= needle) + continue; + char *dir = strchr (line, '/'); if (dir == NULL) continue; - end = strrchr (dir, '/'); + char *file = strrchr (line, '/'); if (end == NULL) continue; - if (strncmp (end + 1, "libvlc.so.", 10)) - continue; - - *end = '\0'; - printf ("libvlc at %s\n", dir); - if (strlen (dir) < sizeof (libvlc_path)) - strcpy (libvlc_path, dir); + *file = '\0'; + if (asprintf (&psz_vlcpath, "%s/"PACKAGE, dir) == -1) + goto error; break; } - + free (line); fclose (maps); + return; + +error: + psz_vlcpath = (char *)default_path; /* default, cannot fail */ } -#endif + +static void unset_libvlc_path (void) +{ + if (psz_vlcpath != default_path) + free (psz_vlcpath); +} + +static struct +{ + vlc_mutex_t lock; + unsigned refs; +} once = { VLC_STATIC_MUTEX, 0 }; #ifdef __GLIBC__ # include @@ -96,20 +107,26 @@ void system_Init (libvlc_int_t *libvlc, int *argc, const char *argv[]) } #endif -#if 0 - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once (&once, set_libvlc_path); -#endif + vlc_mutex_lock (&once.lock); + if (once.refs++ == 0) + set_libvlc_path (); + vlc_mutex_unlock (&once.lock); + (void)libvlc; (void)argc; (void)argv; } -void system_Configure (libvlc_int_t *libvlc, int *argc, const char *argv[]) +void system_Configure (libvlc_int_t *libvlc, + int argc, const char *const argv[]) { (void)libvlc; (void)argc; (void)argv; } void system_End (libvlc_int_t *libvlc) { + vlc_mutex_lock (&once.lock); + if (--once.refs == 0) + unset_libvlc_path (); + vlc_mutex_unlock (&once.lock); + (void)libvlc; } -