Module: wine Branch: master Commit: 995e55371593e4bdcc22aa9e256bb6d42b20f5bf URL: http://source.winehq.org/git/wine.git/?a=commit;h=995e55371593e4bdcc22aa9e25...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Aug 25 12:47:50 2009 +0200
libwine: Determine the bin directory independently from the lib directory if possible.
Prefer the bin directory when getting the data dir location.
---
libs/wine/Makefile.in | 1 - libs/wine/config.c | 155 +++++++++++++++++++++++++++++-------------------- 2 files changed, 91 insertions(+), 65 deletions(-)
diff --git a/libs/wine/Makefile.in b/libs/wine/Makefile.in index 7e7baf1..5af1f94 100644 --- a/libs/wine/Makefile.in +++ b/libs/wine/Makefile.in @@ -111,7 +111,6 @@ CONFIGDIRS = \ -DLIB_TO_BINDIR="`$(RELPATH) $(libdir) $(bindir)`" \ -DLIB_TO_DLLDIR="`$(RELPATH) $(libdir) $(dlldir)`" \ -DBIN_TO_DLLDIR="`$(RELPATH) $(bindir) $(dlldir)`" \ - -DLIB_TO_DATADIR="`$(RELPATH) $(libdir) $(datadir)/wine`" \ -DBIN_TO_DATADIR="`$(RELPATH) $(bindir) $(datadir)/wine`"
config.o: config.c $(RELPATH) diff --git a/libs/wine/config.c b/libs/wine/config.c index 280241c..6bb87b0 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c @@ -137,6 +137,63 @@ static char *get_runtime_libdir(void) return NULL; }
+/* return the directory that contains the main exe at run-time */ +static char *get_runtime_bindir( const char *argv0 ) +{ + char *p, *bindir, *cwd; + size_t len, size; + +#ifdef linux + for (size = 256; ; size *= 2) + { + int ret; + if (!(bindir = malloc( size ))) break; + if ((ret = readlink( "/proc/self/exe", bindir, size )) == -1) break; + if (ret != size) + { + if (!(p = memrchr( bindir, '/', ret ))) break; + if (p == bindir) p++; + *p = 0; + return bindir; + } + free( bindir ); + } + free( bindir ); +#endif + + if (!(p = strrchr( argv0, '/' ))) return NULL; + + 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 + { + /* relative path, make it absolute */ + for (size = 256 + len; ; size *= 2) + { + if (!(cwd = malloc( size ))) return NULL; + 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 NULL; + } + } + return bindir; +} + /* initialize the server directory value */ static void init_server_dir( dev_t dev, ino_t ino ) { @@ -235,6 +292,16 @@ static void init_paths(void) init_server_dir( st.st_dev, st.st_ino ); }
+/* check if bindir is valid by checking for wineserver */ +static int is_valid_bindir( const char *bindir ) +{ + struct stat st; + char *path = build_path( bindir, "wineserver" ); + int ret = (stat( path, &st ) != -1); + free( path ); + return ret; +} + /* check if basedir is a valid build dir by checking for wineserver and ntdll */ /* helper for running_from_build_dir */ static inline int is_valid_build_dir( char *basedir, int baselen ) @@ -252,17 +319,10 @@ static inline int is_valid_build_dir( char *basedir, int baselen ) }
/* check if we are running from the build directory */ -static char *running_from_build_dir( const char *basedir, const char *bindir ) +static char *running_from_build_dir( const char *basedir ) { - struct stat st; const char *p; char *path; - int res; - - if (!(path = build_path( bindir, "wineserver" ))) return NULL; - res = stat( path, &st ); - free( path ); - if (res != -1) return NULL; /* the real bindir is valid */
/* remove last component from basedir */ p = basedir + strlen(basedir) - 1; @@ -289,73 +349,40 @@ static char *running_from_build_dir( const char *basedir, const char *bindir ) /* initialize the argv0 path */ void wine_init_argv0_path( const char *argv0 ) { - size_t size, len; - const char *p, *basename; - char *cwd, *libdir; + const char *basename; + char *libdir;
- if (!(p = strrchr( argv0, '/' ))) - basename = argv0; - else - basename = p + 1; + if (!(basename = strrchr( argv0, '/' ))) basename = argv0; + else basename++;
- argv0_name = xstrdup( basename ); + bindir = get_runtime_bindir( argv0 ); + libdir = get_runtime_libdir();
- if ((libdir = get_runtime_libdir())) + if (bindir && !is_valid_bindir( bindir )) { - bindir = build_path( libdir, LIB_TO_BINDIR ); - if ((build_dir = running_from_build_dir( libdir, bindir ))) - { - free( libdir ); - goto in_build_dir; - } - dlldir = build_path( libdir, LIB_TO_DLLDIR ); - datadir = build_path( libdir, LIB_TO_DATADIR ); - free( libdir ); - return; + build_dir = running_from_build_dir( bindir ); + free( bindir ); + bindir = NULL; + } + if (libdir && !bindir && !build_dir) + { + build_dir = running_from_build_dir( libdir ); + if (!build_dir) bindir = build_path( libdir, LIB_TO_BINDIR ); }
- 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 */ + if (build_dir) { - bindir = xmalloc( len + 1 ); - memcpy( bindir, argv0, len ); - bindir[len] = 0; + argv0_name = build_path( "loader/", basename ); } else { - /* relative path, make it absolute */ - for (size = 256 + len; ; size *= 2) - { - 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; - } - } - - if ((build_dir = running_from_build_dir( bindir, bindir ))) goto in_build_dir; - - dlldir = build_path( bindir, BIN_TO_DLLDIR ); - datadir = build_path( bindir, BIN_TO_DATADIR ); - return; + if (libdir) dlldir = build_path( libdir, LIB_TO_DLLDIR ); + else if (bindir) dlldir = build_path( bindir, BIN_TO_DLLDIR );
-in_build_dir: - free( bindir ); - free( argv0_name ); - bindir = NULL; - argv0_name = build_path( "loader/", basename ); + if (bindir) datadir = build_path( bindir, BIN_TO_DATADIR ); + argv0_name = xstrdup( basename ); + } + free( libdir ); }
/* return the configuration directory ($WINEPREFIX or $HOME/.wine) */