diff mbox series

[v3] util/oslib-posix: : qemu_init_exec_dir implementation for Mac

Message ID CA+XhMqyzW=ah4Q=OCE9KP6DYpiQN18oQpVWjqFCvzQfH3MvQFA@mail.gmail.com
State New
Headers show
Series [v3] util/oslib-posix: : qemu_init_exec_dir implementation for Mac | expand

Commit Message

David CARLIER June 15, 2020, 5:05 p.m. UTC
From dfa1e900dd950f4d3fca17fbf5d3dfb5725c83fa Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen@gmail.com>
Date: Tue, 26 May 2020 21:35:27 +0100
Subject: [PATCH] util/oslib-posix : qemu_init_exec_dir implementation for Mac

Using dyld API to get the full path of the current process.

Signed-off-by: David Carlier <devnexen@gmail.com>
---
 util/oslib-posix.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Peter Maydell June 15, 2020, 7:05 p.m. UTC | #1
On Mon, 15 Jun 2020 at 18:06, David CARLIER <devnexen@gmail.com> wrote:
>
> From dfa1e900dd950f4d3fca17fbf5d3dfb5725c83fa Mon Sep 17 00:00:00 2001
> From: David Carlier <devnexen@gmail.com>
> Date: Tue, 26 May 2020 21:35:27 +0100
> Subject: [PATCH] util/oslib-posix : qemu_init_exec_dir implementation for Mac
>
> Using dyld API to get the full path of the current process.
>
> Signed-off-by: David Carlier <devnexen@gmail.com>

> +#elif defined(__APPLE__)
> +    {
> +        uint32_t len = (uint32_t)sizeof(buf);

Why do we need the cast?

> +        if (_NSGetExecutablePath(buf, &len) == 0) {
> +            buf[len - 1] = 0;
> +            p = buf;
> +        }
> +    }

What does this return if you start QEMU with a relative
path (eg "./qemu-system-x86_64") ?  The documentation
suggests that you need to call realpath() to resolve that kind
of relative path.

Did you try the test I suggested with checking that this
actually does return something different from argv[0] ?

thanks
-- PMM
David CARLIER June 15, 2020, 7:14 p.m. UTC | #2
With this basic program

#include <mach-o/dyld.h>
#include <stdio.h>

int main(void)
{
char buf[4096];
uint32_t bufsize = sizeof(buf);
_NSGetExecutablePath(buf, &bufsize);
printf("%s\n", buf);
return 0;
}

I get

Davids-MacBook-Pro-2:Contribs dcarlier$ ./a.out
/Users/dcarlier/Contribs/./a.out

The cast was to avoid possible warning with pedantic compile flags if used.

On Mon, 15 Jun 2020 at 20:05, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Mon, 15 Jun 2020 at 18:06, David CARLIER <devnexen@gmail.com> wrote:
> >
> > From dfa1e900dd950f4d3fca17fbf5d3dfb5725c83fa Mon Sep 17 00:00:00 2001
> > From: David Carlier <devnexen@gmail.com>
> > Date: Tue, 26 May 2020 21:35:27 +0100
> > Subject: [PATCH] util/oslib-posix : qemu_init_exec_dir implementation for Mac
> >
> > Using dyld API to get the full path of the current process.
> >
> > Signed-off-by: David Carlier <devnexen@gmail.com>
>
> > +#elif defined(__APPLE__)
> > +    {
> > +        uint32_t len = (uint32_t)sizeof(buf);
>
> Why do we need the cast?
>
> > +        if (_NSGetExecutablePath(buf, &len) == 0) {
> > +            buf[len - 1] = 0;
> > +            p = buf;
> > +        }
> > +    }
>
> What does this return if you start QEMU with a relative
> path (eg "./qemu-system-x86_64") ?  The documentation
> suggests that you need to call realpath() to resolve that kind
> of relative path.
>
> Did you try the test I suggested with checking that this
> actually does return something different from argv[0] ?
>
> thanks
> -- PMM
Peter Maydell June 16, 2020, 9:15 a.m. UTC | #3
On Mon, 15 Jun 2020 at 20:14, David CARLIER <devnexen@gmail.com> wrote:
>
> With this basic program
>
> #include <mach-o/dyld.h>
> #include <stdio.h>
>
> int main(void)
> {
> char buf[4096];
> uint32_t bufsize = sizeof(buf);
> _NSGetExecutablePath(buf, &bufsize);
> printf("%s\n", buf);
> return 0;
> }
>
> I get
>
> Davids-MacBook-Pro-2:Contribs dcarlier$ ./a.out
> /Users/dcarlier/Contribs/./a.out

Hmm. I think we should run that through realpath() just
to get rid of the /./ in that. This is similar to how
Chromium uses it (though it uses a different API for
doing the absolutifying):
https://chromium.googlesource.com/chromium/src/base/+/master/base_paths_mac.mm#41

Thanks for the test program, I used it a minor variation of
it to confirm that this does do the right thing even when
argv[0] has been passed as a different string:

$ (exec -a foo /tmp/zz9)
_NSGetExecutablePath: /tmp/zz9
argv[0]: foo

So _NSGetExecutablePath() is definitely the thing to use here.

> The cast was to avoid possible warning with pedantic compile flags if used.

We don't compile with -pedantic, so you don't need to guard
against using it.

thanks
-- PMM
diff mbox series

Patch

diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 916f1be224..0aeaed2fa4 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -57,6 +57,10 @@ 
 #include <lwp.h>
 #endif

+#ifdef __APPLE__
+#include <mach-o/dyld.h>
+#endif
+
 #include "qemu/mmap-alloc.h"

 #ifdef CONFIG_DEBUG_STACK_USAGE
@@ -375,6 +379,14 @@  void qemu_init_exec_dir(const char *argv0)
             p = buf;
         }
     }
+#elif defined(__APPLE__)
+    {
+        uint32_t len = (uint32_t)sizeof(buf);
+        if (_NSGetExecutablePath(buf, &len) == 0) {
+            buf[len - 1] = 0;
+            p = buf;
+        }
+    }
 #endif
     /* If we don't have any way of figuring out the actual executable
        location then try argv[0].  */