From 06680b15b4ee3184b57c9c910886a9ff8a7e58c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 25 May 2022 16:41:26 +0200 Subject: include: move qemu_*_exec_dir() to cutils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function is required by get_relocated_path() (already in cutils), and used by qemu-ga and may be generally useful. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20220525144140.591926-2-marcandre.lureau@redhat.com> --- util/cutils.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) (limited to 'util/cutils.c') diff --git a/util/cutils.c b/util/cutils.c index b277721..a58bcfd 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -26,6 +26,15 @@ #include "qemu/host-utils.h" #include +#ifdef __FreeBSD__ +#include +#include +#endif + +#ifdef __NetBSD__ +#include +#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); -- cgit v1.1