This can be reused by module loading routines. Signed-off-by: Fam Zheng <f...@redhat.com> --- include/qemu/osdep.h | 4 ++++ os-posix.c | 40 ++++++---------------------------------- os-win32.c | 19 +------------------ util/oslib-posix.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ util/oslib-win32.c | 24 ++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 52 deletions(-)
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index b3e2b6d..e680684 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -215,6 +215,10 @@ bool fips_get_state(void); */ char *qemu_get_local_state_pathname(const char *relative_pathname); +/* Find program directory with best effort. Try platform API first, then parse + * argv0 if it's not NULL. The returned string needs to be g_free'ed */ +char *qemu_exec_dir(const char *argv0); + /** * qemu_getauxval: * @type: the auxiliary vector key to lookup diff --git a/os-posix.c b/os-posix.c index d39261d..c5e0722 100644 --- a/os-posix.c +++ b/os-posix.c @@ -86,44 +86,15 @@ void os_setup_signal_handling(void) #define BUILD_SUFFIX "/pc-bios" char *os_find_datadir(const char *argv0) { - char *dir; - char *p = NULL; + char *dir, *exec_dir; char *res; - char buf[PATH_MAX]; size_t max_len; -#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__) - { - static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; - 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; - } - } -#endif - /* If we don't have any way of figuring out the actual executable - location then try argv[0]. */ - if (!p) { - p = realpath(argv0, buf); - if (!p) { - return NULL; - } + exec_dir = qemu_exec_dir(argv0); + if (exec_dir == NULL) { + return NULL; } - dir = dirname(p); - dir = dirname(dir); + dir = dirname(exec_dir); max_len = strlen(dir) + MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1; @@ -137,6 +108,7 @@ char *os_find_datadir(const char *argv0) } } + g_free(exec_dir); return res; } #undef SHARE_SUFFIX diff --git a/os-win32.c b/os-win32.c index 50b7f6f..564d5b4 100644 --- a/os-win32.c +++ b/os-win32.c @@ -86,24 +86,7 @@ void os_setup_early_signal_handling(void) /* Look for support files in the same directory as the executable. */ char *os_find_datadir(const char *argv0) { - char *p; - char buf[MAX_PATH]; - DWORD len; - - len = GetModuleFileName(NULL, buf, sizeof(buf) - 1); - if (len == 0) { - return NULL; - } - - buf[len] = 0; - p = buf + len - 1; - while (p != buf && *p != '\\') - p--; - *p = 0; - if (access(buf, R_OK) == 0) { - return g_strdup(buf); - } - return NULL; + return qemu_exec_dir(argv0); } void os_set_line_buffering(void) diff --git a/util/oslib-posix.c b/util/oslib-posix.c index e00a44c..7c1231f 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -54,6 +54,7 @@ extern int daemon(int, int); #include "trace.h" #include "qemu/sockets.h" #include <sys/mman.h> +#include <libgen.h> #ifdef CONFIG_LINUX #include <sys/syscall.h> @@ -251,3 +252,47 @@ qemu_get_local_state_pathname(const char *relative_pathname) return g_strdup_printf("%s/%s", CONFIG_QEMU_LOCALSTATEDIR, relative_pathname); } + +char *qemu_exec_dir(const char *argv0) +{ + char *dir; + char *p = NULL; + char buf[PATH_MAX]; + +#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__) + { + static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; + 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; + } + } +#endif + /* If we don't have any way of figuring out the actual executable + location then try argv[0]. */ + if (!p) { + if (!argv0) { + return NULL; + } + p = realpath(argv0, buf); + if (!p) { + return NULL; + } + } + dir = dirname(p); + + return g_strdup(dir); +} diff --git a/util/oslib-win32.c b/util/oslib-win32.c index 776ccfa..8605f63 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -189,3 +189,27 @@ qemu_get_local_state_pathname(const char *relative_pathname) return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path, relative_pathname); } + +char *qemu_exec_dir(const char *argv0) +{ + + char *p; + char buf[MAX_PATH]; + DWORD len; + + len = GetModuleFileName(NULL, buf, sizeof(buf) - 1); + if (len == 0) { + return NULL; + } + + buf[len] = 0; + p = buf + len - 1; + while (p != buf && *p != '\\') { + p--; + } + *p = 0; + if (access(buf, R_OK) == 0) { + return g_strdup(buf); + } + return NULL; +} -- 1.8.5.3