summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-03-02 22:17:15 +0000
committerChris Lattner <sabre@nondot.org>2009-03-02 22:17:15 +0000
commit893a0f9f0e8f816c7fb0eb4cfcc972e7e3c68731 (patch)
tree0f81173fba8f365840eaa150bb169c1ca91ed912 /lib
parente3d1b653be98a66390c0064e8a1cfdd3b26b217e (diff)
downloadllvm-893a0f9f0e8f816c7fb0eb4cfcc972e7e3c68731.tar.gz
llvm-893a0f9f0e8f816c7fb0eb4cfcc972e7e3c68731.tar.bz2
llvm-893a0f9f0e8f816c7fb0eb4cfcc972e7e3c68731.tar.xz
Fix main executable path name resolution on FreeBSD, patch by
Ed Schouten! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65882 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/System/Unix/Path.inc61
1 files changed, 60 insertions, 1 deletions
diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc
index 3a651f957c..4a6b505199 100644
--- a/lib/System/Unix/Path.inc
+++ b/lib/System/Unix/Path.inc
@@ -266,10 +266,69 @@ Path::GetCurrentDirectory() {
return Path(pathname);
}
+#ifdef __FreeBSD__
+static int
+test_dir(char buf[PATH_MAX], char ret[PATH_MAX],
+ const char *dir, const char *bin)
+{
+ struct stat sb;
+
+ snprintf(buf, PATH_MAX, "%s//%s", dir, bin);
+ if (realpath(buf, ret) == NULL)
+ return (1);
+ if (stat(buf, &sb) != 0)
+ return (1);
+
+ return (0);
+}
+
+static char *
+getprogpath(char ret[PATH_MAX], const char *bin)
+{
+ char *pv, *s, *t, buf[PATH_MAX];
+
+ /* First approach: absolute path. */
+ if (bin[0] == '/') {
+ if (test_dir(buf, ret, "/", bin) == 0)
+ return (ret);
+ return (NULL);
+ }
+
+ /* Second approach: relative path. */
+ if (strchr(bin, '/') != NULL) {
+ if (getcwd(buf, PATH_MAX) == NULL)
+ return (NULL);
+ if (test_dir(buf, ret, buf, bin) == 0)
+ return (ret);
+ return (NULL);
+ }
+
+ /* Third approach: $PATH */
+ if ((pv = getenv("PATH")) == NULL)
+ return (NULL);
+ s = pv = strdup(pv);
+ if (pv == NULL)
+ return (NULL);
+ while ((t = strsep(&s, ":")) != NULL) {
+ if (test_dir(buf, ret, t, bin) == 0) {
+ free(pv);
+ return (ret);
+ }
+ }
+ free(pv);
+ return (NULL);
+}
+#endif
+
/// GetMainExecutable - Return the path to the main executable, given the
/// value of argv[0] from program startup.
Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
-#if defined(__linux__) || defined(__CYGWIN__)
+#if defined(__FreeBSD__)
+ char exe_path[PATH_MAX];
+
+ if (getprogpath(exe_path, argv0) != NULL)
+ return Path(std::string(exe_path));
+#elif defined(__linux__) || defined(__CYGWIN__)
char exe_path[MAXPATHLEN];
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path));
if (len > 0 && len < MAXPATHLEN - 1) {