Alexandre Julliard : libwine: Set the default bindir and dlldir from argv0 if dladdr is not available.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Feb 17 07:20:50 CST 2006


Module: wine
Branch: refs/heads/master
Commit: e95a2c2111add8d40d486846fae844715577ef56
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=e95a2c2111add8d40d486846fae844715577ef56

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Feb 17 14:08:19 2006 +0100

libwine: Set the default bindir and dlldir from argv0 if dladdr is not available.
Added dependency on $(RELPATH).

---

 libs/wine/Makefile.in |   12 +++-
 libs/wine/config.c    |  133 ++++++++++++++++++++++---------------------------
 2 files changed, 69 insertions(+), 76 deletions(-)

diff --git a/libs/wine/Makefile.in b/libs/wine/Makefile.in
index fb33189..9304175 100644
--- a/libs/wine/Makefile.in
+++ b/libs/wine/Makefile.in
@@ -21,10 +21,14 @@ C_SRCS = \
 CONFIGDIRS = \
 	-DBINDIR='"$(bindir)"' \
 	-DDLLDIR='"$(dlldir)"' \
-	-DBINDIR_REL=\"`$(RELPATH) $(libdir) $(bindir)`\" \
-	-DDLLDIR_REL=\"`$(RELPATH) $(libdir) $(dlldir)`\"
+	-DLIB_TO_BINDIR=\"`$(RELPATH) $(libdir) $(bindir)`\" \
+	-DLIB_TO_DLLDIR=\"`$(RELPATH) $(libdir) $(dlldir)`\" \
+	-DBIN_TO_DLLDIR=\"`$(RELPATH) $(bindir) $(dlldir)`\"
 
-config.o: config.c
-	$(CC) -c $(ALLCFLAGS) -o $@ config.c $(CONFIGDIRS)
+config.o: config.c $(RELPATH)
+	$(CC) -c $(ALLCFLAGS) -o $@ $(SRCDIR)/config.c $(CONFIGDIRS)
+
+$(RELPATH):
+	@cd $(TOOLSDIR)/tools && $(MAKE) relpath
 
 ### Dependencies:
diff --git a/libs/wine/config.c b/libs/wine/config.c
index 4f057bb..65f2857 100644
--- a/libs/wine/config.c
+++ b/libs/wine/config.c
@@ -39,10 +39,11 @@ static const char server_config_dir[] = 
 static const char server_root_prefix[] = "/tmp/.wine-";  /* prefix for server root dir */
 static const char server_dir_prefix[] = "/server-";      /* prefix for server dir */
 
+static char *bindir;
+static char *dlldir;
 static char *config_dir;
 static char *server_dir;
 static char *user_name;
-static char *argv0_path;
 static char *argv0_name;
 
 #ifdef __GNUC__
@@ -101,15 +102,26 @@ inline static void remove_trailing_slash
     while (len > 1 && path[len-1] == '/') path[--len] = 0;
 }
 
+/* build a path from the specified dir and name */
+static char *build_path( const char *dir, const char *name )
+{
+    size_t len = strlen(dir);
+    char *ret = xmalloc( len + strlen(name) + 2 );
+
+    memcpy( ret, dir, len );
+    if (len && ret[len-1] != '/') ret[len++] = '/';
+    strcpy( ret + len, name );
+    return ret;
+}
+
 /* 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 *libdir;
 
-    if (!libdir && dladdr( get_runtime_libdir, &info ) && info.dli_fname[0] == '/')
+    if (dladdr( get_runtime_libdir, &info ) && info.dli_fname[0] == '/')
     {
         const char *p = strrchr( info.dli_fname, '/' );
         unsigned int len = p - info.dli_fname;
@@ -117,42 +129,10 @@ static const char *get_runtime_libdir(vo
         libdir = xmalloc( len + 1 );
         memcpy( libdir, info.dli_fname, len );
         libdir[len] = 0;
+        return libdir;
     }
 #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 *fallback, const char *filename )
-{
-    char *p, *ret;
-    const char *libdir = get_runtime_libdir();
-
-    /* retrieve the library load path */
-
-    if (path[0] && libdir)
-    {
-        ret = xmalloc( strlen(libdir) + strlen(path) + strlen(filename) + 3 );
-        strcpy( ret, libdir );
-        p = ret + strlen(libdir);
-        if (p[-1] != '/') *p++ = '/';
-    }
-    else
-    {
-        if (fallback) path = fallback;
-        ret = p = xmalloc( strlen(path) + strlen(filename) + 2 );
-    }
-
-    strcpy( p, path );
-    p += strlen(p);
-
-    if (*filename)
-    {
-        if (p > ret && p[-1] != '/') *p++ = '/';
-        strcpy( p, filename );
-    }
-    else if (p > ret && p[-1] == '/') p[-1] = 0;
-    return ret;
+    return NULL;
 }
 
 /* initialize the server directory value */
@@ -184,10 +164,7 @@ static void init_server_dir( dev_t dev, 
 /* retrieve the default dll dir */
 const char *get_default_dlldir(void)
 {
-    static const char *dlldir;
-
-    if (!dlldir) dlldir = get_path_from_libdir( DLLDIR_REL, DLLDIR, "" );
-    return dlldir;
+    return dlldir ? dlldir : DLLDIR;
 }
 
 /* initialize all the paths values */
@@ -258,41 +235,53 @@ static void init_paths(void)
 void wine_init_argv0_path( const char *argv0 )
 {
     size_t size, len;
-    const char *p;
+    const char *p, *libdir;
     char *cwd;
 
     if (!(p = strrchr( argv0, '/' )))
-    {
         argv0_name = xstrdup( argv0 );
-        return;  /* if argv0 doesn't contain a path, don't store any path */
-    }
-    else argv0_name = xstrdup( p + 1 );
+    else
+        argv0_name = xstrdup( p + 1 );
 
-    len = p - argv0 + 1;
-    if (argv0[0] == '/')  /* absolute path */
+    if ((libdir = get_runtime_libdir()))
     {
-        argv0_path = xmalloc( len + 1 );
-        memcpy( argv0_path, argv0, len );
-        argv0_path[len] = 0;
+        bindir = build_path( libdir, LIB_TO_BINDIR );
+        dlldir = build_path( libdir, LIB_TO_DLLDIR );
         return;
     }
 
-    /* relative path, make it absolute */
-    for (size = 256 + len; ; size *= 2)
+    if (!p) return;  /* if argv0 doesn't contain a path, don't store anything */
+
+    len = p - argv0;
+    if (!len) len++;  /* include leading slash */
+
+    if (argv0[0] == '/')  /* absolute path */
+    {
+        bindir = xmalloc( len + 1 );
+        memcpy( bindir, argv0, len );
+        bindir[len] = 0;
+    }
+    else
     {
-        if (!(cwd = malloc( size ))) break;
-        if (getcwd( cwd, size - len ))
+        /* relative path, make it absolute */
+        for (size = 256 + len; ; size *= 2)
         {
-            argv0_path = cwd;
-            cwd += strlen(cwd);
-            *cwd++ = '/';
-            memcpy( cwd, argv0, len );
-            cwd[len] = 0;
-            return;
+            if (!(cwd = malloc( size ))) return;
+            if (getcwd( cwd, size - len ))
+            {
+                bindir = cwd;
+                cwd += strlen(cwd);
+                *cwd++ = '/';
+                memcpy( cwd, argv0, len );
+                cwd[len] = 0;
+                break;
+            }
+            free( cwd );
+            if (errno != ERANGE) return;
         }
-        free( cwd );
-        if (errno != ERANGE) break;
     }
+
+    dlldir = build_path( bindir, BIN_TO_DLLDIR );
 }
 
 /* return the configuration directory ($WINEPREFIX or $HOME/.wine) */
@@ -364,7 +353,6 @@ static void preloader_exec( char **argv,
 /* exec a wine internal binary (either the wine loader or the wine server) */
 void wine_exec_wine_binary( const char *name, char **argv, const char *env_var )
 {
-    static const char bindir[] = BINDIR;
     const char *path, *pos, *ptr;
     int use_preloader = 0;
 
@@ -375,9 +363,12 @@ void wine_exec_wine_binary( const char *
     }
 
     /* first, bin directory from the current libdir or argv0 */
-    argv[0] = get_path_from_libdir( BINDIR_REL, argv0_path, name );
-    preloader_exec( argv, use_preloader );
-    free( argv[0] );
+    if (bindir)
+    {
+        argv[0] = build_path( bindir, name );
+        preloader_exec( argv, use_preloader );
+        free( argv[0] );
+    }
 
     /* then specified environment variable */
     if (env_var)
@@ -406,9 +397,7 @@ void wine_exec_wine_binary( const char *
     }
 
     /* and finally try BINDIR */
-    argv[0] = xmalloc( sizeof(bindir) + 1 + strlen(name) );
-    strcpy( argv[0], bindir );
-    strcat( argv[0], "/" );
-    strcat( argv[0], name );
+    argv[0] = build_path( BINDIR, name );
     preloader_exec( argv, use_preloader );
+    free( argv[0] );
 }




More information about the wine-cvs mailing list