summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2015-03-17 20:25:55 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2015-03-17 20:25:55 (GMT)
commit74e7e53ec5ecdd52d1ae626743e737097d28d31b (patch)
tree6ec4818d7de3142abe4fc06405921c0ad0d75bc8
parent4caaca704125b985e050ba4a728d9dd52945c7c5 (diff)
downloadtcl-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.c41
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
}