#include <stdio.h>
#include <string.h>
-#include <sys/stat.h>
#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>
* process might have called setlocale(). */
if (strverscmp (glcv, "2.5") >= 0 && strverscmp (glcv, "2.8") < 0)
{
- fputs ("LibVLC has detected an unusable buggy GNU/libc version.\n",
- stderr);
- fputs ("Please update to version 2.8 or newer.\n", stderr);
+ fputs ("LibVLC has detected an unusable buggy GNU/libc version.\n"
+ "Please update to version 2.8 or newer.\n", stderr);
fflush (stderr);
#ifndef DISABLE_BUGGY_GLIBC_CHECK
abort ();
#endif
}
-
-# ifdef __i386__
- /* glibc 2.10, 2.10.1 fail in pthread_cond_wait on 686 */
- struct stat st;
- if (strverscmp (glcv, "2.10") >= 0
- && strverscmp (glcv, "2.10.1") <= 0 /* update version when fixed */
- && !stat ("/lib/i686/cmov/libpthread.so.0", &st))
- {
- fputs ("LibVLC has detected an unusable buggy GNU/libc version.\n",
- stderr);
- fputs ("Please remove GNU/libc acceleration for 686.\n", stderr);
- fflush (stderr);
-# ifndef DISABLE_BUGGY_GLIBC_CHECK
- abort ();
-# endif
- }
-# endif
#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;
}
-