[llvm-commits] [llvm] r65882 - /llvm/trunk/lib/System/Unix/Path.inc
Chris Lattner
sabre at nondot.org
Mon Mar 2 14:17:16 PST 2009
Author: lattner
Date: Mon Mar 2 16:17:15 2009
New Revision: 65882
URL: http://llvm.org/viewvc/llvm-project?rev=65882&view=rev
Log:
Fix main executable path name resolution on FreeBSD, patch by
Ed Schouten!
Modified:
llvm/trunk/lib/System/Unix/Path.inc
Modified: llvm/trunk/lib/System/Unix/Path.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Unix/Path.inc?rev=65882&r1=65881&r2=65882&view=diff
==============================================================================
--- llvm/trunk/lib/System/Unix/Path.inc (original)
+++ llvm/trunk/lib/System/Unix/Path.inc Mon Mar 2 16:17:15 2009
@@ -266,10 +266,69 @@
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) {
More information about the llvm-commits
mailing list