diff options
author | Fam Zheng <famz@redhat.com> | 2014-02-10 14:48:51 +0800 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-02-20 13:12:54 +0100 |
commit | 10f5bff622cad71645e22c027b77ac31e51008ef (patch) | |
tree | 350ebef38d05121c3b438ef43145c59a0ff7da81 /util/oslib-posix.c | |
parent | 46eef33b89e936ca793e13c4aeea1414e97e8dbb (diff) |
util: Split out exec_dir from os_find_datadir
With this change, main() calls qemu_init_exec_dir and uses argv[0] to
init exec_dir. The saved value can be retrieved with
qemu_get_exec_dir later. It will be reused by module loading.
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'util/oslib-posix.c')
-rw-r--r-- | util/oslib-posix.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/util/oslib-posix.c b/util/oslib-posix.c index d5dca4729a..c2eeb4fe40 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,56 @@ void qemu_set_tty_echo(int fd, bool echo) tcsetattr(fd, TCSANOW, &tty); } + +static char exec_dir[PATH_MAX]; + +void qemu_init_exec_dir(const char *argv0) +{ + char *dir; + char *p = NULL; + char buf[PATH_MAX]; + + assert(!exec_dir[0]); + +#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; + } + p = realpath(argv0, buf); + if (!p) { + return; + } + } + dir = dirname(p); + + pstrcpy(exec_dir, sizeof(exec_dir), dir); +} + +char *qemu_get_exec_dir(void) +{ + return g_strdup(exec_dir); +} |