]> git.proxmox.com Git - mirror_qemu.git/blobdiff - util/oslib-posix.c
util: Split out exec_dir from os_find_datadir
[mirror_qemu.git] / util / oslib-posix.c
index d5dca4729a6590d5acc659d68f859c7c1c954fbd..c2eeb4fe40676212e8acb9855e1b01cd4721236f 100644 (file)
@@ -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);
+}