forked from hasufell/hasufell-repository
270 lines
8.8 KiB
Diff
270 lines
8.8 KiB
Diff
From 97cf70148695df87154ad9fabb312037021a0d82 Mon Sep 17 00:00:00 2001
|
|
From: hasufell <hasufell@gentoo.org>
|
|
Date: Mon, 24 Nov 2014 21:20:43 +0100
|
|
Subject: [PATCH] Query /proc for the executable path on Linux
|
|
|
|
Author: leper
|
|
http://trac.wildfiregames.com/ticket/2086
|
|
http://trac.wildfiregames.com/changeset/15996
|
|
|
|
---
|
|
source/lib/sysdep/os/bsd/bsd.cpp | 46 +-------------
|
|
source/lib/sysdep/os/linux/linux.cpp | 62 +++++++-----------
|
|
.../sysdep/os/unix/unix_executable_pathname.cpp | 73 ++++++++++++++++++++++
|
|
.../lib/sysdep/os/unix/unix_executable_pathname.h | 28 +++++++++
|
|
4 files changed, 124 insertions(+), 85 deletions(-)
|
|
create mode 100644 source/lib/sysdep/os/unix/unix_executable_pathname.cpp
|
|
create mode 100644 source/lib/sysdep/os/unix/unix_executable_pathname.h
|
|
|
|
diff --git a/source/lib/sysdep/os/bsd/bsd.cpp b/source/lib/sysdep/os/bsd/bsd.cpp
|
|
index 34e1460..aa74b98 100644
|
|
--- a/source/lib/sysdep/os/bsd/bsd.cpp
|
|
+++ b/source/lib/sysdep/os/bsd/bsd.cpp
|
|
@@ -23,51 +23,9 @@
|
|
#include "precompiled.h"
|
|
|
|
#include "lib/sysdep/sysdep.h"
|
|
-
|
|
-#define GNU_SOURCE
|
|
-#include "mocks/dlfcn.h"
|
|
-#include "mocks/unistd.h"
|
|
-
|
|
-#include <cstdio>
|
|
+#include "lib/sysdep/os/unix/unix_excecutable_pathname.h"
|
|
|
|
OsPath sys_ExecutablePathname()
|
|
{
|
|
- // Find the executable's filename
|
|
- Dl_info dl_info;
|
|
- memset(&dl_info, 0, sizeof(dl_info));
|
|
- if (!T::dladdr((void *)sys_ExecutablePathname, &dl_info) || !dl_info.dli_fname)
|
|
- return OsPath();
|
|
- const char* path = dl_info.dli_fname;
|
|
-
|
|
- // If this looks like an absolute path, use realpath to get the normalized
|
|
- // path (with no '.' or '..')
|
|
- if (path[0] == '/')
|
|
- {
|
|
- char resolved[PATH_MAX];
|
|
- if (!realpath(path, resolved))
|
|
- return OsPath();
|
|
- return resolved;
|
|
- }
|
|
-
|
|
- // If this looks like a relative path, resolve against cwd and use realpath
|
|
- if (strchr(path, '/'))
|
|
- {
|
|
- char cwd[PATH_MAX];
|
|
- if (!T::getcwd(cwd, PATH_MAX))
|
|
- return OsPath();
|
|
-
|
|
- char absolute[PATH_MAX];
|
|
- int ret = snprintf(absolute, PATH_MAX, "%s/%s", cwd, path);
|
|
- if (ret < 0 || ret >= PATH_MAX)
|
|
- return OsPath(); // path too long, or other error
|
|
- char resolved[PATH_MAX];
|
|
- if (!realpath(absolute, resolved))
|
|
- return OsPath();
|
|
- return resolved;
|
|
- }
|
|
-
|
|
- // If it's not a path at all, i.e. it's just a filename, we'd
|
|
- // probably have to search through PATH to find it.
|
|
- // That's complex and should be uncommon, so don't bother.
|
|
- return OsPath();
|
|
+ return unix_ExecutablePathname();
|
|
}
|
|
diff --git a/source/lib/sysdep/os/linux/linux.cpp b/source/lib/sysdep/os/linux/linux.cpp
|
|
index da2a8ac..d2d47af 100644
|
|
--- a/source/lib/sysdep/os/linux/linux.cpp
|
|
+++ b/source/lib/sysdep/os/linux/linux.cpp
|
|
@@ -23,51 +23,31 @@
|
|
#include "precompiled.h"
|
|
|
|
#include "lib/sysdep/sysdep.h"
|
|
+#include "lib/sysdep/os/unix/unix_executable_pathname.h"
|
|
|
|
-#define GNU_SOURCE
|
|
-#include "mocks/dlfcn.h"
|
|
-#include "mocks/unistd.h"
|
|
-
|
|
-#include <cstdio>
|
|
-
|
|
-OsPath sys_ExecutablePathname()
|
|
+static bool getPathFromProc(char* buffer, size_t length)
|
|
{
|
|
- // Find the executable's filename
|
|
- Dl_info dl_info;
|
|
- memset(&dl_info, 0, sizeof(dl_info));
|
|
- if (!T::dladdr((void *)sys_ExecutablePathname, &dl_info) || !dl_info.dli_fname)
|
|
- return OsPath();
|
|
- const char* path = dl_info.dli_fname;
|
|
+ int pos = readlink("/proc/self/exe", buffer, length-1);
|
|
+ if (pos <= 0)
|
|
+ return false;
|
|
+ buffer[pos] = '\0';
|
|
|
|
- // If this looks like an absolute path, use realpath to get the normalized
|
|
- // path (with no '.' or '..')
|
|
- if (path[0] == '/')
|
|
- {
|
|
- char resolved[PATH_MAX];
|
|
- if (!realpath(path, resolved))
|
|
- return OsPath();
|
|
- return resolved;
|
|
- }
|
|
+ char* endOfPath = strrchr(buffer, '/');
|
|
+ if (endOfPath == NULL)
|
|
+ return false;
|
|
|
|
- // If this looks like a relative path, resolve against cwd and use realpath
|
|
- if (strchr(path, '/'))
|
|
- {
|
|
- char cwd[PATH_MAX];
|
|
- if (!T::getcwd(cwd, PATH_MAX))
|
|
- return OsPath();
|
|
+ ++endOfPath;
|
|
+ *endOfPath = '\0';
|
|
|
|
- char absolute[PATH_MAX];
|
|
- int ret = snprintf(absolute, PATH_MAX, "%s/%s", cwd, path);
|
|
- if (ret < 0 || ret >= PATH_MAX)
|
|
- return OsPath(); // path too long, or other error
|
|
- char resolved[PATH_MAX];
|
|
- if (!realpath(absolute, resolved))
|
|
- return OsPath();
|
|
- return resolved;
|
|
- }
|
|
+ return true;
|
|
+}
|
|
+
|
|
+OsPath sys_ExecutablePathname()
|
|
+{
|
|
+ // Check /proc for the path
|
|
+ char pathBuffer[PATH_MAX];
|
|
+ if (getPathFromProc(pathBuffer, sizeof(pathBuffer)))
|
|
+ return pathBuffer;
|
|
|
|
- // If it's not a path at all, i.e. it's just a filename, we'd
|
|
- // probably have to search through PATH to find it.
|
|
- // That's complex and should be uncommon, so don't bother.
|
|
- return OsPath();
|
|
+ return unix_ExecutablePathname();
|
|
}
|
|
diff --git a/source/lib/sysdep/os/unix/unix_executable_pathname.cpp b/source/lib/sysdep/os/unix/unix_executable_pathname.cpp
|
|
new file mode 100644
|
|
index 0000000..ae7b989
|
|
--- /dev/null
|
|
+++ b/source/lib/sysdep/os/unix/unix_executable_pathname.cpp
|
|
@@ -0,0 +1,73 @@
|
|
+/* Copyright (c) 2014 Wildfire Games
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining
|
|
+ * a copy of this software and associated documentation files (the
|
|
+ * "Software"), to deal in the Software without restriction, including
|
|
+ * without limitation the rights to use, copy, modify, merge, publish,
|
|
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
|
+ * permit persons to whom the Software is furnished to do so, subject to
|
|
+ * the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be included
|
|
+ * in all copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
+ */
|
|
+
|
|
+#include "precompiled.h"
|
|
+
|
|
+#include "lib/sysdep/sysdep.h"
|
|
+
|
|
+#define GNU_SOURCE
|
|
+#include "mocks/dlfcn.h"
|
|
+#include "mocks/unistd.h"
|
|
+
|
|
+#include <cstdio>
|
|
+
|
|
+OsPath unix_ExecutablePathname()
|
|
+{
|
|
+ // Find the executable's filename
|
|
+ Dl_info dl_info;
|
|
+ memset(&dl_info, 0, sizeof(dl_info));
|
|
+ if (!T::dladdr((void *)sys_ExecutablePathname, &dl_info) || !dl_info.dli_fname)
|
|
+ return OsPath();
|
|
+ const char* path = dl_info.dli_fname;
|
|
+
|
|
+ // If this looks like an absolute path, use realpath to get the normalized
|
|
+ // path (with no '.' or '..')
|
|
+ if (path[0] == '/')
|
|
+ {
|
|
+ char resolved[PATH_MAX];
|
|
+ if (!realpath(path, resolved))
|
|
+ return OsPath();
|
|
+ return resolved;
|
|
+ }
|
|
+
|
|
+ // If this looks like a relative path, resolve against cwd and use realpath
|
|
+ if (strchr(path, '/'))
|
|
+ {
|
|
+ char cwd[PATH_MAX];
|
|
+ if (!T::getcwd(cwd, PATH_MAX))
|
|
+ return OsPath();
|
|
+
|
|
+ char absolute[PATH_MAX];
|
|
+ int ret = snprintf(absolute, PATH_MAX, "%s/%s", cwd, path);
|
|
+ if (ret < 0 || ret >= PATH_MAX)
|
|
+ return OsPath(); // path too long, or other error
|
|
+ char resolved[PATH_MAX];
|
|
+ if (!realpath(absolute, resolved))
|
|
+ return OsPath();
|
|
+ return resolved;
|
|
+ }
|
|
+
|
|
+ // If it's not a path at all, i.e. it's just a filename, we'd
|
|
+ // probably have to search through PATH to find it.
|
|
+ // That's complex and should be uncommon, so don't bother.
|
|
+ return OsPath();
|
|
+}
|
|
diff --git a/source/lib/sysdep/os/unix/unix_executable_pathname.h b/source/lib/sysdep/os/unix/unix_executable_pathname.h
|
|
new file mode 100644
|
|
index 0000000..f87c340
|
|
--- /dev/null
|
|
+++ b/source/lib/sysdep/os/unix/unix_executable_pathname.h
|
|
@@ -0,0 +1,28 @@
|
|
+/* Copyright (c) 2014 Wildfire Games
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining
|
|
+ * a copy of this software and associated documentation files (the
|
|
+ * "Software"), to deal in the Software without restriction, including
|
|
+ * without limitation the rights to use, copy, modify, merge, publish,
|
|
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
|
+ * permit persons to whom the Software is furnished to do so, subject to
|
|
+ * the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be included
|
|
+ * in all copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
+ */
|
|
+
|
|
+#ifndef INCLUDED_UNIX_EXECUTABLE_PATHNAME
|
|
+#define INCLUDED_UNIX_EXECUTABLE_PATHNAME
|
|
+
|
|
+OsPath unix_ExecutablePathname();
|
|
+
|
|
+#endif // INCLUDED_UNIX_EXECUTABLE_PATHNAME
|
|
--
|
|
2.1.3
|
|
|