summaryrefslogtreecommitdiffstats
path: root/src/path-prefix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/path-prefix.cpp')
-rw-r--r--src/path-prefix.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/path-prefix.cpp b/src/path-prefix.cpp
index eefe7ff39..a2b7c9fbc 100644
--- a/src/path-prefix.cpp
+++ b/src/path-prefix.cpp
@@ -12,6 +12,14 @@
# include "config.h" // only include where actually required!
#endif
+#ifdef _WIN32
+#include <windows.h> // for GetModuleFileNameW
+#endif
+
+#ifdef __APPLE__
+#include <mach-o/dyld.h> // for _NSGetExecutablePath
+#endif
+
#include "io/resource.h"
#include "path-prefix.h"
#include <glib.h>
@@ -115,6 +123,63 @@ gchar *get_datadir_path()
return datadir;
}
+
+/**
+ * Gets the the currently running program's executable name (including full path)
+ *
+ * @return executable name (including full path) encoded as UTF-8
+ * or NULL if it can't be determined
+ */
+gchar *get_program_name()
+{
+ static gchar *program_name = NULL;
+
+ if (program_name == NULL) {
+ // There is no portable way to get an executable's name including path, so we need to do it manually.
+ // TODO: Re-evaluate boost::dll::program_location() once we require Boost >= 1.61
+ //
+ // The following platform-specific code is partially based on GdxPixbuf's get_toplevel()
+ // See also https://stackoverflow.com/a/1024937
+#if defined(_WIN32)
+ wchar_t module_file_name[MAX_PATH];
+ if (GetModuleFileNameW(NULL, module_file_name, MAX_PATH)) {
+ program_name = g_utf16_to_utf8((gunichar2 *)module_file_name, -1, NULL, NULL, NULL);
+ } else {
+ g_warning("get_program_name() - GetModuleFileNameW failed");
+ }
+#elif defined(__APPLE__)
+ char pathbuf[PATH_MAX + 1];
+ uint32_t bufsize = sizeof(pathbuf);
+ if (_NSGetExecutablePath(pathbuf, &bufsize) == 0) {
+ program_name = g_strdup(pathbuf);
+ } else {
+ g_warning("get_program_name() - _NSGetExecutablePath failed");
+ }
+#elif defined(__linux__)
+ program_name = g_file_read_link("/proc/self/exe", NULL);
+ if (!program_name) {
+ g_warning("get_program_name() - g_file_read_link failed");
+ }
+#else
+#warning get_program_name() - no known way to obtain executable name on this platform
+ g_info("get_program_name() - no known way to obtain executable name on this platform");
+#endif
+ }
+
+ return program_name;
+}
+
+/**
+ * Gets the the full path to the directory containing the currently running program's executable
+ *
+ * @return full path to directory encoded as UTF-8
+ * or NULL if it can't be determined
+ */
+gchar *get_program_dir()
+{
+ return g_path_get_dirname(get_program_name());
+}
+
/*
Local Variables:
mode:c++