]> git.sesse.net Git - vlc/commitdiff
Compute the lib directory dynamically
authorRémi Denis-Courmont <remi@remlab.net>
Tue, 24 Jan 2012 18:46:40 +0000 (20:46 +0200)
committerRémi Denis-Courmont <remi@remlab.net>
Tue, 24 Jan 2012 19:02:14 +0000 (21:02 +0200)
On Linux, this simplifies the code and improves relocability.
On Windows, OS/2 and MacOS, this should fix a small race condition.

13 files changed:
include/vlc_configuration.h
modules/lua/vlc.c
src/libvlc.h
src/modules/bank.c
src/os2/dirs.c
src/os2/specific.c
src/posix/darwin_dirs.c
src/posix/darwin_specific.c
src/posix/dirs.c
src/posix/linux_specific.c
src/posix/specific.c
src/win32/dirs.c
src/win32/specific.c

index bc248f7b28449e1de6f71effcc653e5be5533611..e01103bacefc993b4c1b11e1b7f3e98abc9cab88 100644 (file)
@@ -196,7 +196,7 @@ VLC_API void config_ResetAll( vlc_object_t * );
 VLC_API module_config_t * config_FindConfig( vlc_object_t *, const char * ) VLC_USED;
 VLC_API char * config_GetDataDir( vlc_object_t * ) VLC_USED VLC_MALLOC;
 #define config_GetDataDir(a) config_GetDataDir(VLC_OBJECT(a))
-VLC_API const char * config_GetLibDir( void ) VLC_USED;
+VLC_API char *config_GetLibDir(void) VLC_USED;
 VLC_API const char * config_GetConfDir( void ) VLC_USED;
 
 typedef enum vlc_userdir
index a0132cfa78cf62bcd1d46eaed712405fe9445dc1..a14f24abaefef8e8b447da21fea71cbc4b9f8bb9 100644 (file)
@@ -230,9 +230,14 @@ int vlclua_dir_list( vlc_object_t *p_this, const char *luadirname,
     free( datadir );
 
 #if !(defined(__APPLE__) || defined(WIN32) || defined(__OS2__))
-    if( likely(asprintf( &ppsz_dir_list[i], "%s"DIR_SEP"lua"DIR_SEP"%s",
-                         config_GetLibDir(), luadirname ) != -1) )
+    char *psz_libpath = config_GetLibDir();
+    if( likely(psz_libpath != NULL) )
+    {
+        if( likely(asprintf( &ppsz_dir_list[i], "%s"DIR_SEP"lua"DIR_SEP"%s",
+                             psz_libpath, luadirname ) != -1) )
             i++;
+        free( psz_libpath );
+    }
 #endif
 
     char *psz_datapath = config_GetDataDir( p_this );
index dcf032d4ead22126f95adad40af45d4b526a536d..e5a3185dccd8015d2b185c5f9d80a21f7c58f84f 100644 (file)
@@ -119,8 +119,6 @@ void vlc_object_set_destructor (vlc_object_t *, vlc_destructor_t);
 /*
  * To be cleaned-up module stuff:
  */
-extern char *psz_vlcpath;
-
 module_t *module_find_by_shortcut (const char *psz_shortcut);
 
 /**
index eb253c8f742bbfd5bc5696cb2973aec10fb09d99..5e79094a08a954ba728dcfb541655f3e72d1aa8a 100644 (file)
@@ -245,8 +245,6 @@ module_t **module_list_get (size_t *n)
     return tab;
 }
 
-char *psz_vlcpath = NULL;
-
 #ifdef HAVE_DYNAMIC_PLUGINS
 typedef enum { CACHE_USE, CACHE_RESET, CACHE_IGNORE } cache_mode_t;
 
@@ -262,7 +260,6 @@ static void AllocatePluginPath (vlc_object_t *, const char *, cache_mode_t);
  */
 static void AllocateAllPlugins (vlc_object_t *p_this)
 {
-    const char *vlcpath = psz_vlcpath;
     char *paths;
     cache_mode_t mode;
 
@@ -275,13 +272,14 @@ static void AllocateAllPlugins (vlc_object_t *p_this)
 
     /* Contruct the special search path for system that have a relocatable
      * executable. Set it to <vlc path>/plugins. */
-    assert( vlcpath );
-
-    if( asprintf( &paths, "%s" DIR_SEP "plugins", vlcpath ) != -1 )
+    char *vlcpath = config_GetLibDir ();
+    if (likely(vlcpath != NULL)
+     && likely(asprintf (&paths, "%s" DIR_SEP "plugins", vlcpath) != -1))
     {
         AllocatePluginPath (p_this, paths, mode);
         free( paths );
     }
+    free (vlcpath);
 
     /* If the user provided a plugin path, we add it to the list */
     paths = getenv( "VLC_PLUGIN_PATH" );
index c3994bc963ab6ed52a518ae19a156b79ba82ec75..c710b124bc129e328aac19b3af7a9534cec5c99d 100644 (file)
 #include <vlc_charset.h>
 #include "config/configuration.h"
 
-static char *config_GetVlcDir (void)
+char *config_GetLibDir (void)
 {
-    return FromLocaleDup (psz_vlcpath);
+    HMODULE hmod;
+    CHAR    psz_path[CCHMAXPATH + 4];
+
+    DosQueryModFromEIP( &hmod, NULL, 0, NULL, NULL, ( ULONG )system_Init );
+    DosQueryModuleName( hmod, sizeof( psz_path ), psz_path );
+
+    /* remove the DLL name */
+    char *slash = strrchr( psz_path, '\\');
+    if( slash == NULL )
+        abort();
+    strcpy(slash + 1, PACKAGE);
+    return FromLocaleDup(psz_path);
 }
 
 /**
@@ -42,7 +53,7 @@ static char *config_GetVlcDir (void)
  */
 char *config_GetDataDirDefault (void)
 {
-    char *datadir = config_GetVlcDir();
+    char *datadir = config_GetLibDir();
 
     if (datadir)
         /* replace last lib\vlc with share */
@@ -51,16 +62,6 @@ char *config_GetDataDirDefault (void)
     return datadir;
 }
 
-/**
- * Determines the architecture-dependent data directory
- *
- * @return a string (always succeeds).
- */
-const char *config_GetLibDir (void)
-{
-    abort ();
-}
-
 /**
  * Determines the system configuration directory.
  *
@@ -68,7 +69,8 @@ const char *config_GetLibDir (void)
  */
 const char *config_GetConfDir( void )
 {
-    return config_GetVlcDir ();
+#warning FIXME: memory leak
+    return config_GetLibDir ();
 }
 
 char *config_GetUserDir (vlc_userdir_t type)
@@ -89,5 +91,5 @@ char *config_GetUserDir (vlc_userdir_t type)
         case VLC_VIDEOS_DIR:
             break;
     }
-    return config_GetVlcDir ();
+    return config_GetLibDir ();
 }
index 6d2e61cf7df13ebeb5f9d40f44e6b9f658393b14..5db0b187f2c722dadf5a740f373fa13b83d5ceed 100644 (file)
@@ -32,25 +32,6 @@ extern int _fmode_bin;
 
 void system_Init( void )
 {
-    HMODULE hmod;
-    CHAR    psz_path[ CCHMAXPATH ];
-    PSZ     psz_dirsep;
-
-    DosQueryModFromEIP( &hmod, NULL, 0, NULL, NULL, ( ULONG )system_Init );
-    DosQueryModuleName( hmod, sizeof( psz_path ), psz_path );
-
-    /* remove the DLL name */
-    psz_dirsep = strrchr( psz_path, '\\');
-    if( psz_dirsep )
-        *psz_dirsep = '\0';
-
-    DosEnterCritSec();
-
-    if( !psz_vlcpath )
-        asprintf( &psz_vlcpath, "%s\\vlc", psz_path );
-
-    DosExitCritSec();
-
     /* Set the default file-translation mode */
     _fmode_bin = 1;
     setmode( fileno( stdin ), O_BINARY ); /* Needed for pipes */
@@ -74,6 +55,4 @@ void system_Configure( libvlc_int_t *p_this, int i_argc, const char *const ppsz_
 
 void system_End( void )
 {
-    free( psz_vlcpath );
-    psz_vlcpath = NULL;
 }
index cb35b366dc4595666d1d47005db4d3b5c82cc50f..b809449c89b7d93260709cf47c2401b47428bbff 100644 (file)
@@ -2,7 +2,7 @@
  * darwin_dirs.c: Mac OS X directories configuration
  *****************************************************************************
  * Copyright (C) 2001-2009 VLC authors and VideoLAN
- * Copyright © 2007-2009 Rémi Denis-Courmont
+ * Copyright © 2007-2012 Rémi Denis-Courmont
  *
  * Authors: Gildas Bazin <gbazin@videolan.org>
  *          Felix Paul Kühne <fkuehne at videolan dot org>
 #include <vlc_configuration.h>
 #include "config/configuration.h"
 
+#include <libgen.h>
+#include <dlfcn.h>
+#include <mach-o/dyld.h>
+
 static char *configdir = NULL;
 
 static pthread_once_t once = PTHREAD_ONCE_INIT;
@@ -50,20 +54,80 @@ const char *config_GetConfDir( void )
     return configdir;
 }
 
-char *config_GetDataDirDefault (void)
+static char *config_GetLibPath (void)
 {
-    char *datadir;
+    /* Get the full program path and name */
+    /* First try to see if we are linked to the framework */
+    for (unsigned i = 0; i < _dyld_image_count(); i++)
+    {
+        const char *psz_img_name = _dyld_get_image_name(i);
+        const char *p = strstr( psz_img_name, "VLCKit.framework/Versions/" );
 
-    if (asprintf (&datadir, "%s/share", psz_vlcpath) == -1)
-        return NULL;
-    return datadir;
+        /* Check for "VLCKit.framework/Versions/Current/VLCKit",
+         * as well as "VLCKit.framework/Versions/A/VLCKit" and
+         * "VLC.framework/Versions/B/VLCKit" */
+        if( p != NULL )
+        {
+            /* Look for the next forward slash */
+            p += 26; /* p_char += strlen(" VLCKit.framework/Versions/" ) */
+            p += strcspn( p, "/" );
+
+            /* If the string ends with VLC then we've found a winner */
+            if ( !strcmp( p, "/VLCKit" ) )
+                return strdup( psz_img_name );
+        }
+
+        /* Do we end by "VLC"? If so we are the legacy VLC.app that doesn't
+         * link to VLCKit. */
+        size_t len = strlen(psz_img_name);
+        if( len >= 3 && !strcmp( psz_img_name + len - 3, "VLC") )
+            return strdup( psz_img_name );
+    }
+
+    /* We are not linked to the VLC.framework, let's use dladdr to figure
+     * libvlc path */
+    Dl_info info;
+    if( dladdr(system_Init, &info) )
+        return strdup(dirname( info.dli_fname ));
+
+    char path[MAXPATHLEN+1];
+    uint32_t path_len = sizeof(path) - 1;
+
+    if ( !_NSGetExecutablePath(path, &path_len) )
+         return strdup(path);
+    return NULL;
 }
 
-const char *config_GetLibDir (void)
+char *config_GetLibDir (void)
 {
+    char *path = config_GetLibPath ();
+    if (path != NULL)
+    {
+        char *p = strrchr (p, '/');
+        if (p != NULL)
+        {
+            *p = '\0';
+            return path;
+        }
+        free (path);
+    }
+
+    /* should never happen */
     abort ();
 }
 
+char *config_GetDataDirDefault (void)
+{
+    char *vlcpath = config_GetLibDir ();
+    char *datadir;
+
+    if (asprintf (&datadir, "%s/share", vlcpath) == -1)
+        datadir = NULL;
+
+    free (vlcpath);
+    return datadir;
+}
+
 static char *config_GetHomeDir (void)
 {
     const char *home = getenv ("HOME");
index 4d8195b09ee605c9a37beb667abebdb73d991936..50f20be8cf2334611d35ed2d161a667f55510922 100644 (file)
 #include <vlc_common.h>
 #include "../libvlc.h"
 #include <dirent.h>                                                /* *dir() */
-#include <libgen.h>
-#include <dlfcn.h>
 #include <CoreFoundation/CoreFoundation.h>
-#include <mach-o/dyld.h>
 
 #ifdef HAVE_LOCALE_H
 #   include <locale.h>
  *****************************************************************************/
 void system_Init(void)
 {
-    char i_dummy;
-    char *p_char = NULL;
-    char *p_oldchar = &i_dummy;
-    unsigned int i;
-
-    /* Get the full program path and name */
-    /* First try to see if we are linked to the framework */
-    for (i = 0; i < _dyld_image_count(); i++)
-    {
-        const char * psz_img_name = _dyld_get_image_name(i);
-        /* Check for "VLCKit.framework/Versions/Current/VLCKit",
-         * as well as "VLCKit.framework/Versions/A/VLCKit" and
-         * "VLC.framework/Versions/B/VLCKit" */
-        if( (p_char = strstr( psz_img_name, "VLCKit.framework/Versions/" )) )
-        {
-            /* Look for the next forward slash */
-            p_char += 26; /* p_char += strlen(" VLCKit.framework/Versions/" ) */
-            while( *p_char != '\0' && *p_char != '/')
-                p_char++;
-
-            /* If the string ends with VLC then we've found a winner */
-            if ( !strcmp( p_char, "/VLCKit" ) )
-            {
-                p_char = strdup( psz_img_name );
-                break;
-            }
-            else
-                p_char = NULL;
-        }
-        else
-        {
-            size_t len = strlen(psz_img_name);
-            /* Do we end by "VLC"? If so we are the legacy VLC.app that doesn't
-             * link to VLCKit. */
-            if( !strcmp( psz_img_name + len - 3, "VLC") )
-            {
-                p_char = strdup( psz_img_name );
-                break;
-            }
-        }
-    }
-    if ( !p_char )
-    {
-        /* We are not linked to the VLC.framework, let's use dladdr to figure
-         * libvlc path */
-        Dl_info info;
-        if( dladdr(system_Init, &info) )
-            p_char = strdup(dirname( info.dli_fname ));
-    }
-    if( !p_char )
-    {
-        char path[MAXPATHLEN+1];
-        uint32_t path_len = MAXPATHLEN;
-        if ( !_NSGetExecutablePath(path, &path_len) )
-            p_char = strdup(path);
-    }
-
-    free(psz_vlcpath);
-    psz_vlcpath = p_char;
-
-    /* Remove trailing program name */
-    for( ; *p_char ; )
-    {
-        if( *p_char == '/' )
-        {
-            *p_oldchar = '/';
-            *p_char = '\0';
-            p_oldchar = p_char;
-        }
-        p_char++;
-    }
-
 #ifdef ENABLE_NLS
     /* Check if $LANG is set. */
     if( NULL == getenv("LANG") )
@@ -168,7 +93,5 @@ void system_Configure( libvlc_int_t *p_this,
  *****************************************************************************/
 void system_End( void )
 {
-    free( psz_vlcpath );
-    psz_vlcpath = NULL;
 }
 
index 5a445f3b6947916fb0c27072a10f0a0c91f0c008..eb31a5698cace7037f6327b0bad15e2df89d1b24 100644 (file)
@@ -46,15 +46,17 @@ char *config_GetDataDirDefault (void)
     return strdup (DATA_PATH);
 }
 
+#if !defined (__linux__)
 /**
  * Determines the architecture-dependent data directory
  *
  * @return a string (always succeeds).
  */
-const char *config_GetLibDir (void)
+char *config_GetLibDir (void)
 {
-    return PKGLIBDIR;
+    return strdup (PKGLIBDIR);
 }
+#endif
 
 /**
  * Determines the system configuration directory.
index 37fb047c8989ba8b54c293c9f37611150d592d88..28dbed1bae4c8a91efbe27bb1b2556f9503eed5a 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * linux_specific.c: Linux-specific initialization
  *****************************************************************************
- * Copyright © 2008 Rémi Denis-Courmont
+ * Copyright © 2008-2012 Rémi Denis-Courmont
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
 #include <vlc_common.h>
 #include "../libvlc.h"
 
-static const char default_path[] = PKGLIBDIR;
-
-static void set_libvlc_path (void)
+char *config_GetLibDir (void)
 {
+    char *path = NULL;
+
     /* Find the path to libvlc (i.e. ourselves) */
     FILE *maps = fopen ("/proc/self/maps", "rt");
     if (maps == NULL)
@@ -39,7 +39,7 @@ static void set_libvlc_path (void)
 
     char *line = NULL;
     size_t linelen = 0;
-    uintptr_t needle = (uintptr_t)set_libvlc_path;
+    uintptr_t needle = (uintptr_t)config_GetLibDir;
 
     for (;;)
     {
@@ -50,39 +50,30 @@ static void set_libvlc_path (void)
         void *start, *end;
         if (sscanf (line, "%p-%p", &start, &end) < 2)
             continue;
+        /* This mapping contains the address of this function. */
         if (needle < (uintptr_t)start || (uintptr_t)end <= needle)
             continue;
+
         char *dir = strchr (line, '/');
         if (dir == NULL)
             continue;
+
         char *file = strrchr (line, '/');
         if (end == NULL)
             continue;
         *file = '\0';
-        if (asprintf (&psz_vlcpath, "%s/"PACKAGE, dir) == -1)
-            goto error;
+
+        if (asprintf (&path, "%s/"PACKAGE, dir) == -1)
+            path = NULL;
         break;
     }
+
     free (line);
     fclose (maps);
-    return;
-
 error:
-    psz_vlcpath = (char *)default_path; /* default, cannot fail */
+    return (path != NULL) ? path : strdup (PKGLIBDIR);
 }
 
-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>
 # include <stdlib.h>
@@ -103,11 +94,6 @@ void system_Init (void)
         fflush (stderr);
     }
 #endif
-
-    vlc_mutex_lock (&once.lock);
-    if (once.refs++ == 0)
-        set_libvlc_path ();
-    vlc_mutex_unlock (&once.lock);
 }
 
 void system_Configure (libvlc_int_t *libvlc,
@@ -118,8 +104,4 @@ void system_Configure (libvlc_int_t *libvlc,
 
 void system_End (void)
 {
-    vlc_mutex_lock (&once.lock);
-    if (--once.refs == 0)
-        unset_libvlc_path ();
-    vlc_mutex_unlock (&once.lock);
 }
index 7f6fdce1d436bac933f99e5f441f68e94ec1dcc3..0a65fb3359f9f6d56db8542a5dbcc16f94695b34 100644 (file)
 
 #include <vlc_common.h>
 #include "../libvlc.h"
-#include <pthread.h>
-
-static void set_libvlc_path (void)
-{
-    psz_vlcpath = (char *)PKGLIBDIR;
-}
 
 void system_Init (void)
 {
-    pthread_once_t once = PTHREAD_ONCE_INIT;
-
-    pthread_once (&once, set_libvlc_path);
 }
 
 void system_Configure (libvlc_int_t *libvlc,
index c46ded58c79ef067cd98e865fe319680f0e3ab11..d874c85e7e78e4c834c830a4ee53f5b8f2a23873 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
  * dirs.c: directories configuration
  *****************************************************************************
- * Copyright (C) 2001-2007 VLC authors and VideoLAN
- * Copyright © 2007-2008 Rémi Denis-Courmont
+ * Copyright (C) 2001-2010 VLC authors and VideoLAN
+ * Copyright © 2007-2012 Rémi Denis-Courmont
  *
  * Authors: Gildas Bazin <gbazin@videolan.org>
  *
@@ -25,6 +25,7 @@
 # include "config.h"
 #endif
 
+#define UNICODE
 #include <vlc_common.h>
 
 #include <w32api.h>
 #include <assert.h>
 #include <limits.h>
 
-char *config_GetDataDirDefault( void )
+char *config_GetLibDir (void)
 {
-    return strdup (psz_vlcpath);
+    /* Get our full path */
+    MEMORY_BASIC_INFORMATION mbi;
+    if (!VirtualQuery (config_GetLibDir, &mbi, sizeof(mbi)))
+        goto error;
+
+    wchar_t wpath[MAX_PATH];
+    if (!GetModuleFileName ((HMODULE) mbi.AllocationBase, wpath, MAX_PATH))
+        goto error;
+
+    wchar_t *file = wcsrchr (wpath, L'\\');
+    if (file == NULL)
+        goto error;
+    *file = L'\0';
+
+    return FromWide (wpath);
+error:
+    abort ();
 }
 
-const char *config_GetLibDir (void)
+char *config_GetDataDirDefault( void )
 {
-    abort ();
+    return config_GetLibDir ();
 }
 
 const char *config_GetConfDir (void)
index 8942b51f512a9ac6ee9256d840ba3c9032ad91aa..8a20808b33b2dc5bd32984078edbc9d542f1d308 100644 (file)
 void system_Init( void )
 {
     WSADATA Data;
-    MEMORY_BASIC_INFORMATION mbi;
-
-    /* Get our full path */
-    char psz_path[MAX_PATH];
-    char *psz_vlc;
-
-    wchar_t psz_wpath[MAX_PATH];
-    if( VirtualQuery(system_Init, &mbi, sizeof(mbi) ) )
-    {
-        HMODULE hMod = (HMODULE) mbi.AllocationBase;
-        if( GetModuleFileName( hMod, psz_wpath, MAX_PATH ) )
-        {
-            WideCharToMultiByte( CP_UTF8, 0, psz_wpath, -1,
-                                psz_path, MAX_PATH, NULL, NULL );
-        }
-        else psz_path[0] = '\0';
-    }
-    else psz_path[0] = '\0';
-
-    psz_vlc = strrchr( psz_path, '\\' );
-    if( psz_vlc )
-        *psz_vlc = '\0';
-
-    {
-        /* remove trailing \.libs from executable dir path if seen,
-           we assume we are running vlc through libtool wrapper in build dir */
-        size_t len = strlen(psz_path);
-        if( len >= 5 && !stricmp(psz_path + len - 5, "\\.libs" ) )
-            psz_path[len - 5] = '\0';
-    }
-
-    psz_vlcpath = strdup( psz_path );
 
 #if !defined( UNDER_CE )
     timeBeginPeriod(5);
@@ -366,9 +334,6 @@ void system_End( void )
 {
     HWND ipcwindow;
 
-    free( psz_vlcpath );
-    psz_vlcpath = NULL;
-
     /* FIXME: thread-safety... */
     if (p_helper)
     {