From: Fam Zheng <f...@redhat.com> This can be reused by module loading routines.
Signed-off-by: Fam Zheng <f...@redhat.com> Signed-off-by: Paolo Bonzini <pbonz...@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 eac7172..9e329ca 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 d5dca47..372b2f9 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -57,6 +57,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> @@ -274,3 +275,47 @@ void qemu_set_tty_echo(int fd, bool echo) tcsetattr(fd, TCSANOW, &tty); } + +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 50be044..9ce22a1 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -208,3 +208,27 @@ void qemu_set_tty_echo(int fd, bool echo) dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT)); } } + +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.3.1