diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2015-03-17 20:25:55 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2015-03-17 20:25:55 (GMT) |
commit | 74e7e53ec5ecdd52d1ae626743e737097d28d31b (patch) | |
tree | 6ec4818d7de3142abe4fc06405921c0ad0d75bc8 | |
parent | 4caaca704125b985e050ba4a728d9dd52945c7c5 (diff) | |
download | tcl-bug_1224888.zip tcl-bug_1224888.tar.gz tcl-bug_1224888.tar.bz2 |
Added better way to find executable name on OSX.bug_1224888
-rw-r--r-- | unix/tclUnixFile.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c index 19610d7..5ac3fd5 100644 --- a/unix/tclUnixFile.c +++ b/unix/tclUnixFile.c @@ -15,6 +15,9 @@ #if !defined(NO_DLADDR) && !defined(NO_DLFCN_H) #include <dlfcn.h> #endif +#ifdef __APPLE__ +#include <mach-o/dyld.h> +#endif static int NativeMatchType(Tcl_Interp *interp, const char* nativeEntry, const char* nativeName, Tcl_GlobTypeData *types); @@ -47,6 +50,7 @@ TclpFindExecutable( int length; char buf[PATH_MAX * 2]; char name[PATH_MAX * TCL_UTF_MAX + 1]; + GetModuleFileNameW(NULL, buf, PATH_MAX); cygwin_conv_path(3, buf, name, PATH_MAX); length = strlen(name); @@ -61,11 +65,15 @@ TclpFindExecutable( const char *name, *p; Tcl_StatBuf statBuf; Tcl_DString buffer, nameString, cwd, utfName; -#if !defined(__APPLE__) && !defined(DJGPP) +#ifdef __APPLE__ + char *buf; + uint32_t bufSize; +#elif !defined(DJGPP) int i; unsigned long pid; static CONST char *exepaths[] = { - "/proc/%lu/exe", "/proc/%lu/file", "/proc/%lu/object/a.out" + "/proc/%lu/exe", "/proc/%lu/file", "/proc/%lu/object/a.out", + "/proc/curproc/file" }; char buf1[PATH_MAX+1], buf2[64]; #endif @@ -89,8 +97,31 @@ TclpFindExecutable( * /proc (if that's mounted, and we have readlink(2)) or to pick the * information out of the dynamic loader (assuming we're using a * compatible one and it supports the relevant - common - extension). + * + * On OSX, we can use the _NSGetExecutablePath function to retrieve the + * name of the main process. This is documented on the dyld(3) manual + * page. + * + * For a list of various techniques and links to more details on how to + * implement them, see the Stack Overflow master question at + * http://stackoverflow.com/q/1023306/301832 */ +#ifdef __APPLE__ + buf = NULL; + bufSize = 0; + _NSGetExecutablePath(buf, &bufSize); + if (bufSize > 0) { + buf = ckalloc(bufSize+1); + if (_NSGetExecutablePath(buf, &bufSize) == 0) { + name = buf; + goto gotName; + } + ckfree(buf); + buf = NULL; + } +#endif /* __APPLE__ */ + #if !defined(__APPLE__) && !defined(DJGPP) pid = getpid(); for (i=0 ; i<sizeof(exepaths)/sizeof(*exepaths) ; i++) { @@ -101,6 +132,7 @@ TclpFindExecutable( } } #endif + #if !defined(NO_DLADDR) && !defined(NO_DLFCN_H) sym = dlsym(RTLD_DEFAULT, "main"); if (sym == NULL) { @@ -237,6 +269,11 @@ TclpFindExecutable( Tcl_DStringFree(&utfName); done: +#ifdef __APPLE__ + if (buf != NULL) { + ckfree(buf); + } +#endif /* __APPLE__ */ Tcl_DStringFree(&buffer); #endif } |