If an executable is run through a symlink, dladdr will return the
authorChris Lattner <sabre@nondot.org>
Thu, 19 Feb 2009 05:34:35 +0000 (05:34 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 19 Feb 2009 05:34:35 +0000 (05:34 +0000)
symlink.  We really want the ultimate executable being run, not
the symlink.  This lets clang find its headers when invoked through
a symlink. rdar://6602012

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65017 91177308-0d34-0410-b5e6-96231b3b80d8

lib/System/Unix/Path.inc

index a8dcedb7417947e34e45df5290ca529a5b56eebf..3a651f957cd0aa5f37ae3ac8f33e848a1cc6e4b4 100644 (file)
@@ -117,7 +117,7 @@ Path::GetRootDirectory() {
 }
 
 Path
-Path::GetTemporaryDirectory(std::string* ErrMsg ) {
+Path::GetTemporaryDirectory(std::string *ErrMsg) {
 #if defined(HAVE_MKDTEMP)
   // The best way is with mkdtemp but that's not available on many systems,
   // Linux and FreeBSD have it. Others probably won't.
@@ -280,8 +280,13 @@ Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
   // Use dladdr to get executable path if available.
   Dl_info DLInfo;
   int err = dladdr(MainAddr, &DLInfo);
-  if (err != 0)
-    return Path(std::string(DLInfo.dli_fname));
+  if (err == 0)
+    return Path();
+  
+  // If the filename is a symlink, we need to resolve and return the location of
+  // the actual executable.
+  char link_path[MAXPATHLEN];
+  return Path(std::string(realpath(DLInfo.dli_fname, link_path)));
 #endif
   return Path();
 }