libwine: Use dladdr if supported to get the run-time path of libwine.so
and define the default dll and bin directories relative to it.
This commit is contained in:
parent
266c609dd1
commit
0b34fb3656
|
@ -5,7 +5,7 @@ VPATH = @srcdir@
|
||||||
LIBRARY = wine
|
LIBRARY = wine
|
||||||
SOVERSION = 1
|
SOVERSION = 1
|
||||||
VERSCRIPT = $(SRCDIR)/wine.map
|
VERSCRIPT = $(SRCDIR)/wine.map
|
||||||
EXTRADEFS = -D__WINESRC__ -DBINDIR="\"$(bindir)\"" -DDLLDIR="\"$(dlldir)\""
|
EXTRADEFS = -D__WINESRC__ -DBINDIR="\"$(bindir)\"" -DLIBDIR="\"$(libdir)\"" -DDLLDIR="\"$(dlldir)\""
|
||||||
EXTRALIBS = $(LIBPORT) @DLLIBS@ @CRTLIBS@ @LDLIBWINEFLAGS@
|
EXTRALIBS = $(LIBPORT) @DLLIBS@ @CRTLIBS@ @LDLIBWINEFLAGS@
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
|
|
|
@ -101,6 +101,103 @@ inline static void remove_trailing_slashes( char *path )
|
||||||
while (len > 1 && path[len-1] == '/') path[--len] = 0;
|
while (len > 1 && path[len-1] == '/') path[--len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* determine where the destination path is located relative to the 'from' path */
|
||||||
|
inline static const char *get_relative_path( const char *from, const char *dest, unsigned int *dotdots )
|
||||||
|
{
|
||||||
|
#define DIR_END(p) (*(p) == 0 || *(p) == '/')
|
||||||
|
const char *start;
|
||||||
|
|
||||||
|
*dotdots = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
while (*from == '/') from++;
|
||||||
|
while (*dest == '/') dest++;
|
||||||
|
start = dest; /* save start of next path element */
|
||||||
|
if (!*from) break;
|
||||||
|
|
||||||
|
while (!DIR_END(from) && *from == *dest) { from++; dest++; }
|
||||||
|
if (DIR_END(from) && DIR_END(dest)) continue;
|
||||||
|
|
||||||
|
/* count remaining elements in 'from' */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
(*dotdots)++;
|
||||||
|
while (!DIR_END(from)) from++;
|
||||||
|
while (*from == '/') from++;
|
||||||
|
}
|
||||||
|
while (*from);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return start;
|
||||||
|
#undef DIR_END
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the directory that contains the library at run-time */
|
||||||
|
static const char *get_runtime_libdir(void)
|
||||||
|
{
|
||||||
|
static char *libdir;
|
||||||
|
|
||||||
|
#ifdef HAVE_DLADDR
|
||||||
|
Dl_info info;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (!libdir && dladdr( get_runtime_libdir, &info ) && (p = strrchr( info.dli_fname, '/' )))
|
||||||
|
{
|
||||||
|
unsigned int len = p - info.dli_fname;
|
||||||
|
if (!len) len++; /* include initial slash */
|
||||||
|
libdir = xmalloc( len + 1 );
|
||||||
|
memcpy( libdir, info.dli_fname, len );
|
||||||
|
libdir[len] = 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_DLADDR */
|
||||||
|
return libdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine the proper location of the given path based on the current libdir */
|
||||||
|
static char *get_path_from_libdir( const char *path, const char *filename )
|
||||||
|
{
|
||||||
|
char *p, *ret;
|
||||||
|
const char *libdir = get_runtime_libdir();
|
||||||
|
|
||||||
|
/* retrieve the library load path */
|
||||||
|
|
||||||
|
if (libdir)
|
||||||
|
{
|
||||||
|
unsigned int dotdots = 0;
|
||||||
|
const char *start = get_relative_path( LIBDIR, path, &dotdots );
|
||||||
|
|
||||||
|
ret = xmalloc( strlen(libdir) + 3 * dotdots + strlen(start) + strlen(filename) + 3 );
|
||||||
|
strcpy( ret, libdir );
|
||||||
|
p = ret + strlen(libdir);
|
||||||
|
if (p[-1] != '/') *p++ = '/';
|
||||||
|
|
||||||
|
while (dotdots--)
|
||||||
|
{
|
||||||
|
p[0] = '.';
|
||||||
|
p[1] = '.';
|
||||||
|
p[2] = '/';
|
||||||
|
p += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy( p, start );
|
||||||
|
p += strlen(p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = xmalloc( strlen(path) + strlen(filename) + 2 );
|
||||||
|
strcpy( ret, path );
|
||||||
|
p = ret + strlen(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*filename)
|
||||||
|
{
|
||||||
|
if (p[-1] != '/') *p++ = '/';
|
||||||
|
strcpy( p, filename );
|
||||||
|
}
|
||||||
|
else if (p[-1] == '/') p[-1] = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize the server directory value */
|
/* initialize the server directory value */
|
||||||
static void init_server_dir( dev_t dev, ino_t ino )
|
static void init_server_dir( dev_t dev, ino_t ino )
|
||||||
{
|
{
|
||||||
|
@ -127,6 +224,15 @@ static void init_server_dir( dev_t dev, ino_t ino )
|
||||||
sprintf( p, "%lx", (unsigned long)ino );
|
sprintf( p, "%lx", (unsigned long)ino );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* retrieve the default dll dir */
|
||||||
|
const char *get_default_dlldir(void)
|
||||||
|
{
|
||||||
|
static const char *dlldir;
|
||||||
|
|
||||||
|
if (!dlldir) dlldir = get_path_from_libdir( DLLDIR, "" );
|
||||||
|
return dlldir;
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize all the paths values */
|
/* initialize all the paths values */
|
||||||
static void init_paths(void)
|
static void init_paths(void)
|
||||||
{
|
{
|
||||||
|
@ -314,9 +420,7 @@ void wine_exec_wine_binary( const char *name, char **argv, char **envp, int use_
|
||||||
else if (!name) name = argv0_name;
|
else if (!name) name = argv0_name;
|
||||||
|
|
||||||
/* first, try bin directory */
|
/* first, try bin directory */
|
||||||
argv[0] = xmalloc( sizeof(BINDIR "/") + strlen(name) );
|
argv[0] = get_path_from_libdir( BINDIR, name );
|
||||||
strcpy( argv[0], BINDIR "/" );
|
|
||||||
strcat( argv[0], name );
|
|
||||||
preloader_exec( argv, envp, use_preloader );
|
preloader_exec( argv, envp, use_preloader );
|
||||||
free( argv[0] );
|
free( argv[0] );
|
||||||
|
|
||||||
|
|
|
@ -74,13 +74,14 @@ static const IMAGE_NT_HEADERS *main_exe;
|
||||||
|
|
||||||
static load_dll_callback_t load_dll_callback;
|
static load_dll_callback_t load_dll_callback;
|
||||||
|
|
||||||
static const char default_dlldir[] = DLLDIR;
|
static const char *default_dlldir;
|
||||||
static const char **dll_paths;
|
static const char **dll_paths;
|
||||||
static int nb_dll_paths;
|
static int nb_dll_paths;
|
||||||
static int dll_path_maxlen;
|
static int dll_path_maxlen;
|
||||||
|
|
||||||
extern void mmap_init(void);
|
extern void mmap_init(void);
|
||||||
extern void debug_init(void);
|
extern void debug_init(void);
|
||||||
|
extern const char *get_default_dlldir(void);
|
||||||
|
|
||||||
/* build the dll load path from the WINEDLLPATH variable */
|
/* build the dll load path from the WINEDLLPATH variable */
|
||||||
static void build_dll_path(void)
|
static void build_dll_path(void)
|
||||||
|
@ -121,7 +122,8 @@ static void build_dll_path(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* append default dll dir (if not empty) to path */
|
/* append default dll dir (if not empty) to path */
|
||||||
if ((len = sizeof(default_dlldir)-1))
|
default_dlldir = get_default_dlldir();
|
||||||
|
if ((len = strlen(default_dlldir)) > 0)
|
||||||
{
|
{
|
||||||
if (len > dll_path_maxlen) dll_path_maxlen = len;
|
if (len > dll_path_maxlen) dll_path_maxlen = len;
|
||||||
dll_paths[nb_dll_paths++] = default_dlldir;
|
dll_paths[nb_dll_paths++] = default_dlldir;
|
||||||
|
|
Loading…
Reference in New Issue