]> git.sesse.net Git - vlc/blobdiff - src/misc/linux_specific.c
Use var_Inherit* instead of var_CreateGet*.
[vlc] / src / misc / linux_specific.c
index 79c880742b1dc4635f68a2899541e5b379cf5109..1644ce62133cdbeca5c8f16b97e3ace0b0df2cf4 100644 (file)
 #include <vlc_common.h>
 #include "../libvlc.h"
 
-#if 0
-#include <assert.h>
-#include <pthread.h>
+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 <gnu/libc-version.h>
@@ -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;
 }
-