diff options
Diffstat (limited to 'util/cutils.c')
-rw-r--r-- | util/cutils.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/util/cutils.c b/util/cutils.c index b2777210e7..a58bcfd80e 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -26,6 +26,15 @@ #include "qemu/host-utils.h" #include <math.h> +#ifdef __FreeBSD__ +#include <sys/sysctl.h> +#include <sys/user.h> +#endif + +#ifdef __NetBSD__ +#include <sys/sysctl.h> +#endif + #include "qemu/ctype.h" #include "qemu/cutils.h" #include "qemu/error-report.h" @@ -931,6 +940,114 @@ static inline const char *next_component(const char *dir, int *p_len) return dir; } +static const char *exec_dir; + +void qemu_init_exec_dir(const char *argv0) +{ +#ifdef G_OS_WIN32 + char *p; + char buf[MAX_PATH]; + DWORD len; + + if (exec_dir) { + return; + } + + len = GetModuleFileName(NULL, buf, sizeof(buf) - 1); + if (len == 0) { + return; + } + + buf[len] = 0; + p = buf + len - 1; + while (p != buf && *p != '\\') { + p--; + } + *p = 0; + if (access(buf, R_OK) == 0) { + exec_dir = g_strdup(buf); + } else { + exec_dir = CONFIG_BINDIR; + } +#else + char *p = NULL; + char buf[PATH_MAX]; + + if (exec_dir) { + return; + } + +#if defined(__linux__) + { + int len; + len = readlink("/proc/self/exe", buf, sizeof(buf) - 1); + if (len > 0) { + buf[len] = 0; + p = buf; + } + } +#elif defined(__FreeBSD__) \ + || (defined(__NetBSD__) && defined(KERN_PROC_PATHNAME)) + { +#if defined(__FreeBSD__) + static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; +#else + static int mib[4] = {CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME}; +#endif + size_t len = sizeof(buf) - 1; + + *buf = '\0'; + if (!sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) && + *buf) { + buf[sizeof(buf) - 1] = '\0'; + p = buf; + } + } +#elif defined(__APPLE__) + { + char fpath[PATH_MAX]; + uint32_t len = sizeof(fpath); + if (_NSGetExecutablePath(fpath, &len) == 0) { + p = realpath(fpath, buf); + if (!p) { + return; + } + } + } +#elif defined(__HAIKU__) + { + image_info ii; + int32_t c = 0; + + *buf = '\0'; + while (get_next_image_info(0, &c, &ii) == B_OK) { + if (ii.type == B_APP_IMAGE) { + strncpy(buf, ii.name, sizeof(buf)); + buf[sizeof(buf) - 1] = 0; + p = buf; + break; + } + } + } +#endif + /* If we don't have any way of figuring out the actual executable + location then try argv[0]. */ + if (!p && argv0) { + p = realpath(argv0, buf); + } + if (p) { + exec_dir = g_path_get_dirname(p); + } else { + exec_dir = CONFIG_BINDIR; + } +#endif +} + +const char *qemu_get_exec_dir(void) +{ + return exec_dir; +} + char *get_relocated_path(const char *dir) { size_t prefix_len = strlen(CONFIG_PREFIX); |