Commit 97fbfd88 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Compute the lib directory dynamically

On Linux, this simplifies the code and improves relocability.
On Windows, OS/2 and MacOS, this should fix a small race condition.
parent 2171af17
...@@ -196,7 +196,7 @@ VLC_API void config_ResetAll( vlc_object_t * ); ...@@ -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 module_config_t * config_FindConfig( vlc_object_t *, const char * ) VLC_USED;
VLC_API char * config_GetDataDir( vlc_object_t * ) VLC_USED VLC_MALLOC; VLC_API char * config_GetDataDir( vlc_object_t * ) VLC_USED VLC_MALLOC;
#define config_GetDataDir(a) config_GetDataDir(VLC_OBJECT(a)) #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; VLC_API const char * config_GetConfDir( void ) VLC_USED;
typedef enum vlc_userdir typedef enum vlc_userdir
......
...@@ -230,9 +230,14 @@ int vlclua_dir_list( vlc_object_t *p_this, const char *luadirname, ...@@ -230,9 +230,14 @@ int vlclua_dir_list( vlc_object_t *p_this, const char *luadirname,
free( datadir ); free( datadir );
#if !(defined(__APPLE__) || defined(WIN32) || defined(__OS2__)) #if !(defined(__APPLE__) || defined(WIN32) || defined(__OS2__))
if( likely(asprintf( &ppsz_dir_list[i], "%s"DIR_SEP"lua"DIR_SEP"%s", char *psz_libpath = config_GetLibDir();
config_GetLibDir(), luadirname ) != -1) ) if( likely(psz_libpath != NULL) )
{
if( likely(asprintf( &ppsz_dir_list[i], "%s"DIR_SEP"lua"DIR_SEP"%s",
psz_libpath, luadirname ) != -1) )
i++; i++;
free( psz_libpath );
}
#endif #endif
char *psz_datapath = config_GetDataDir( p_this ); char *psz_datapath = config_GetDataDir( p_this );
......
...@@ -119,8 +119,6 @@ void vlc_object_set_destructor (vlc_object_t *, vlc_destructor_t); ...@@ -119,8 +119,6 @@ void vlc_object_set_destructor (vlc_object_t *, vlc_destructor_t);
/* /*
* To be cleaned-up module stuff: * To be cleaned-up module stuff:
*/ */
extern char *psz_vlcpath;
module_t *module_find_by_shortcut (const char *psz_shortcut); module_t *module_find_by_shortcut (const char *psz_shortcut);
/** /**
......
...@@ -245,8 +245,6 @@ module_t **module_list_get (size_t *n) ...@@ -245,8 +245,6 @@ module_t **module_list_get (size_t *n)
return tab; return tab;
} }
char *psz_vlcpath = NULL;
#ifdef HAVE_DYNAMIC_PLUGINS #ifdef HAVE_DYNAMIC_PLUGINS
typedef enum { CACHE_USE, CACHE_RESET, CACHE_IGNORE } cache_mode_t; 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); ...@@ -262,7 +260,6 @@ static void AllocatePluginPath (vlc_object_t *, const char *, cache_mode_t);
*/ */
static void AllocateAllPlugins (vlc_object_t *p_this) static void AllocateAllPlugins (vlc_object_t *p_this)
{ {
const char *vlcpath = psz_vlcpath;
char *paths; char *paths;
cache_mode_t mode; cache_mode_t mode;
...@@ -275,13 +272,14 @@ static void AllocateAllPlugins (vlc_object_t *p_this) ...@@ -275,13 +272,14 @@ static void AllocateAllPlugins (vlc_object_t *p_this)
/* Contruct the special search path for system that have a relocatable /* Contruct the special search path for system that have a relocatable
* executable. Set it to <vlc path>/plugins. */ * executable. Set it to <vlc path>/plugins. */
assert( vlcpath ); char *vlcpath = config_GetLibDir ();
if (likely(vlcpath != NULL)
if( asprintf( &paths, "%s" DIR_SEP "plugins", vlcpath ) != -1 ) && likely(asprintf (&paths, "%s" DIR_SEP "plugins", vlcpath) != -1))
{ {
AllocatePluginPath (p_this, paths, mode); AllocatePluginPath (p_this, paths, mode);
free( paths ); free( paths );
} }
free (vlcpath);
/* If the user provided a plugin path, we add it to the list */ /* If the user provided a plugin path, we add it to the list */
paths = getenv( "VLC_PLUGIN_PATH" ); paths = getenv( "VLC_PLUGIN_PATH" );
......
...@@ -30,9 +30,20 @@ ...@@ -30,9 +30,20 @@
#include <vlc_charset.h> #include <vlc_charset.h>
#include "config/configuration.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) ...@@ -42,7 +53,7 @@ static char *config_GetVlcDir (void)
*/ */
char *config_GetDataDirDefault (void) char *config_GetDataDirDefault (void)
{ {
char *datadir = config_GetVlcDir(); char *datadir = config_GetLibDir();
if (datadir) if (datadir)
/* replace last lib\vlc with share */ /* replace last lib\vlc with share */
...@@ -51,16 +62,6 @@ char *config_GetDataDirDefault (void) ...@@ -51,16 +62,6 @@ char *config_GetDataDirDefault (void)
return datadir; return datadir;
} }
/**
* Determines the architecture-dependent data directory
*
* @return a string (always succeeds).
*/
const char *config_GetLibDir (void)
{
abort ();
}
/** /**
* Determines the system configuration directory. * Determines the system configuration directory.
* *
...@@ -68,7 +69,8 @@ const char *config_GetLibDir (void) ...@@ -68,7 +69,8 @@ const char *config_GetLibDir (void)
*/ */
const char *config_GetConfDir( void ) const char *config_GetConfDir( void )
{ {
return config_GetVlcDir (); #warning FIXME: memory leak
return config_GetLibDir ();
} }
char *config_GetUserDir (vlc_userdir_t type) char *config_GetUserDir (vlc_userdir_t type)
...@@ -89,5 +91,5 @@ char *config_GetUserDir (vlc_userdir_t type) ...@@ -89,5 +91,5 @@ char *config_GetUserDir (vlc_userdir_t type)
case VLC_VIDEOS_DIR: case VLC_VIDEOS_DIR:
break; break;
} }
return config_GetVlcDir (); return config_GetLibDir ();
} }
...@@ -32,25 +32,6 @@ extern int _fmode_bin; ...@@ -32,25 +32,6 @@ extern int _fmode_bin;
void system_Init( void ) 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 */ /* Set the default file-translation mode */
_fmode_bin = 1; _fmode_bin = 1;
setmode( fileno( stdin ), O_BINARY ); /* Needed for pipes */ 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_ ...@@ -74,6 +55,4 @@ void system_Configure( libvlc_int_t *p_this, int i_argc, const char *const ppsz_
void system_End( void ) void system_End( void )
{ {
free( psz_vlcpath );
psz_vlcpath = NULL;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* darwin_dirs.c: Mac OS X directories configuration * darwin_dirs.c: Mac OS X directories configuration
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2009 VLC authors and VideoLAN * 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> * Authors: Gildas Bazin <gbazin@videolan.org>
* Felix Paul Kühne <fkuehne at videolan dot org> * Felix Paul Kühne <fkuehne at videolan dot org>
...@@ -35,6 +35,10 @@ ...@@ -35,6 +35,10 @@
#include <vlc_configuration.h> #include <vlc_configuration.h>
#include "config/configuration.h" #include "config/configuration.h"
#include <libgen.h>
#include <dlfcn.h>
#include <mach-o/dyld.h>
static char *configdir = NULL; static char *configdir = NULL;
static pthread_once_t once = PTHREAD_ONCE_INIT; static pthread_once_t once = PTHREAD_ONCE_INIT;
...@@ -50,20 +54,80 @@ const char *config_GetConfDir( void ) ...@@ -50,20 +54,80 @@ const char *config_GetConfDir( void )
return configdir; 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) /* Check for "VLCKit.framework/Versions/Current/VLCKit",
return NULL; * as well as "VLCKit.framework/Versions/A/VLCKit" and
return datadir; * "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 (); 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) static char *config_GetHomeDir (void)
{ {
const char *home = getenv ("HOME"); const char *home = getenv ("HOME");
......
...@@ -31,10 +31,7 @@ ...@@ -31,10 +31,7 @@
#include <vlc_common.h> #include <vlc_common.h>
#include "../libvlc.h" #include "../libvlc.h"
#include <dirent.h> /* *dir() */ #include <dirent.h> /* *dir() */
#include <libgen.h>
#include <dlfcn.h>
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
#include <mach-o/dyld.h>
#ifdef HAVE_LOCALE_H #ifdef HAVE_LOCALE_H
# include <locale.h> # include <locale.h>
...@@ -49,78 +46,6 @@ ...@@ -49,78 +46,6 @@
*****************************************************************************/ *****************************************************************************/
void system_Init(void) 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 #ifdef ENABLE_NLS
/* Check if $LANG is set. */ /* Check if $LANG is set. */
if( NULL == getenv("LANG") ) if( NULL == getenv("LANG") )
...@@ -168,7 +93,5 @@ void system_Configure( libvlc_int_t *p_this, ...@@ -168,7 +93,5 @@ void system_Configure( libvlc_int_t *p_this,
*****************************************************************************/ *****************************************************************************/
void system_End( void ) void system_End( void )
{ {
free( psz_vlcpath );
psz_vlcpath = NULL;
} }
...@@ -46,15 +46,17 @@ char *config_GetDataDirDefault (void) ...@@ -46,15 +46,17 @@ char *config_GetDataDirDefault (void)
return strdup (DATA_PATH); return strdup (DATA_PATH);
} }
#if !defined (__linux__)
/** /**
* Determines the architecture-dependent data directory * Determines the architecture-dependent data directory
* *
* @return a string (always succeeds). * @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. * Determines the system configuration directory.
......
/***************************************************************************** /*****************************************************************************
* linux_specific.c: Linux-specific initialization * 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 * 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 * under the terms of the GNU Lesser General Public License as published by
...@@ -28,10 +28,10 @@ ...@@ -28,10 +28,10 @@
#include <vlc_common.h> #include <vlc_common.h>
#include "../libvlc.h" #include "../libvlc.h"
static const char default_path[] = PKGLIBDIR; char *config_GetLibDir (void)
static void set_libvlc_path (void)
{ {
char *path = NULL;
/* Find the path to libvlc (i.e. ourselves) */ /* Find the path to libvlc (i.e. ourselves) */
FILE *maps = fopen ("/proc/self/maps", "rt"); FILE *maps = fopen ("/proc/self/maps", "rt");
if (maps == NULL) if (maps == NULL)
...@@ -39,7 +39,7 @@ static void set_libvlc_path (void) ...@@ -39,7 +39,7 @@ static void set_libvlc_path (void)
char *line = NULL; char *line = NULL;
size_t linelen = 0; size_t linelen = 0;
uintptr_t needle = (uintptr_t)set_libvlc_path; uintptr_t needle = (uintptr_t)config_GetLibDir;
for (;;) for (;;)
{ {
...@@ -50,39 +50,30 @@ static void set_libvlc_path (void) ...@@ -50,39 +50,30 @@ static void set_libvlc_path (void)
void *start, *end; void *start, *end;
if (sscanf (line, "%p-%p", &start, &end) < 2) if (sscanf (line, "%p-%p", &start, &end) < 2)
continue; continue;
/* This mapping contains the address of this function. */
if (needle < (uintptr_t)start || (uintptr_t)end <= needle) if (needle < (uintptr_t)start || (uintptr_t)end <= needle)
continue; continue;
char *dir = strchr (line, '/'); char *dir = strchr (line, '/');
if (dir == NULL) if (dir == NULL)
continue; continue;
char *file = strrchr (line, '/'); char *file = strrchr (line, '/');
if (end == NULL) if (end == NULL)
continue; continue;
*file = '\0'; *file = '\0';
if (asprintf (&psz_vlcpath, "%s/"PACKAGE, dir) == -1)
goto error; if (asprintf (&path, "%s/"PACKAGE, dir) == -1)
path = NULL;
break; break;
} }
free (line); free (line);
fclose (maps); fclose (maps);
return;
error: 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__ #ifdef __GLIBC__
# include <gnu/libc-version.h> # include <gnu/libc-version.h>
# include <stdlib.h> # include <stdlib.h>
...@@ -103,11 +94,6 @@ void system_Init (void) ...@@ -103,11 +94,6 @@ void system_Init (void)
fflush (stderr); fflush (stderr);
} }
#endif #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, void system_Configure (libvlc_int_t *libvlc,
...@@ -118,8 +104,4 @@ void system_Configure (libvlc_int_t *libvlc, ...@@ -118,8 +104,4 @@ void system_Configure (libvlc_int_t *libvlc,
void system_End (void) void system_End (void)
{ {
vlc_mutex_lock (&once.lock);
if (--once.refs == 0)
unset_libvlc_path ();
vlc_mutex_unlock (&once.lock);
} }
...@@ -24,18 +24,9 @@ ...@@ -24,18 +24,9 @@
#include <vlc_common.h> #include <vlc_common.h>
#include "../libvlc.h" #include "../libvlc.h"
#include <pthread.h>
static void set_libvlc_path (void)
{
psz_vlcpath = (char *)PKGLIBDIR;
}
void system_Init (void) void system_Init (void)
{ {
pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_once (&once, set_libvlc_path);
} }
void system_Configure (libvlc_int_t *libvlc, void system_Configure (libvlc_int_t *libvlc,
......
/***************************************************************************** /*****************************************************************************
* dirs.c: directories configuration * dirs.c: directories configuration
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2007 VLC authors and VideoLAN * Copyright (C) 2001-2010 VLC authors and VideoLAN
* Copyright © 2007-2008 Rémi Denis-Courmont * Copyright © 2007-2012 Rémi Denis-Courmont
* *
* Authors: Gildas Bazin <gbazin@videolan.org> * Authors: Gildas Bazin <gbazin@videolan.org>
* *
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
# include "config.h" # include "config.h"
#endif #endif
#define UNICODE
#include <vlc_common.h> #include <vlc_common.h>
#include <w32api.h> #include <w32api.h>
...@@ -41,14 +42,30 @@ ...@@ -41,14 +42,30 @@
#include <assert.h> #include <assert.h>
#include <limits.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) const char *config_GetConfDir (void)
......
...@@ -45,38 +45,6 @@ ...@@ -45,38 +45,6 @@
void system_Init( void ) void system_Init( void )
{ {
WSADATA Data; 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 ) #if !defined( UNDER_CE )
timeBeginPeriod(5); timeBeginPeriod(5);
...@@ -366,9 +334,6 @@ void system_End( void ) ...@@ -366,9 +334,6 @@ void system_End( void )
{ {
HWND ipcwindow; HWND ipcwindow;
free( psz_vlcpath );
psz_vlcpath = NULL;
/* FIXME: thread-safety... */ /* FIXME: thread-safety... */
if (p_helper) if (p_helper)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment