diff options
author | David Turner <digit@android.com> | 2011-07-15 14:46:26 +0200 |
---|---|---|
committer | David Turner <digit@android.com> | 2011-07-15 14:46:26 +0200 |
commit | add001c9d30ef442e87ee18ec59342929401bd49 (patch) | |
tree | 78080d3ea9920958b0143837570006ecb8fa936a /android/main-emulator.c | |
parent | 01ced5e66b05c7ce8c446340e8bf8387cdfad356 (diff) | |
download | external_qemu-add001c9d30ef442e87ee18ec59342929401bd49.zip external_qemu-add001c9d30ef442e87ee18ec59342929401bd49.tar.gz external_qemu-add001c9d30ef442e87ee18ec59342929401bd49.tar.bz2 |
Fix Windows space-in-path handling for 'emulator'.
This modifies the 'emulator' launcher program to work
correctly on Windows when it is installed in a path that
contains spaces.
The program computed the path of the program to be launched
correctly, but it turns out that the problem is in the
implementation of execv() in either mingw or MSVCRT.DLL:
experimentation shows that one needs to quote argv[0] when
it contains spaces. However, you must *not* quote the first
argument to execv(), otherwise the call will fail.
Change-Id: If291c5a8bd507f96b40634ecbc946ba38346ee4e
Diffstat (limited to 'android/main-emulator.c')
-rw-r--r-- | android/main-emulator.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/android/main-emulator.c b/android/main-emulator.c index 211291b..39e5e1e 100644 --- a/android/main-emulator.c +++ b/android/main-emulator.c @@ -44,6 +44,23 @@ int android_verbose; /* Forward declarations */ static char* getTargetEmulatorPath(const char* progName, const char* avdArch); +#ifdef _WIN32 +static char* quotePath(const char* path); +#endif + +/* The execv() definition in mingw is slightly bogus. + * It takes a second argument of type 'const char* const*' + * while POSIX mandates char** instead. + * + * To avoid compiler warnings, define the safe_execv macro + * to perform an explicit cast with mingw. + */ +#ifdef _WIN32 +# define safe_execv(_filepath,_argv) execv((_filepath),(const char* const*)(_argv)) +#else +# define safe_execv(_filepath,_argv) execv((_filepath),(_argv)) +#endif + /* Main routine */ int main(int argc, char** argv) { @@ -109,9 +126,20 @@ int main(int argc, char** argv) /* Replace it in our command-line */ argv[0] = emulatorPath; +#ifdef _WIN32 + /* Looks like execv() in mingw (or is it MSVCRT.DLL?) doesn't + * support a space in argv[0] unless we explicitely quote it. + * IMPORTANT: do not quote the first argument to execv() or it will fail. + * This was tested on a 32-bit Vista installation. + */ + if (strchr(emulatorPath, ' ')) { + argv[0] = quotePath(emulatorPath); + D("Quoted emulator binary path: %s\n", emulatorPath); + } +#endif + /* Launch it with the same set of options ! */ - /* execv() should be available on Windows with mingw32 */ - execv(emulatorPath, argv); + safe_execv(emulatorPath, argv); /* We could not launch the program ! */ fprintf(stderr, "Could not launch '%s': %s\n", emulatorPath, strerror(errno)); @@ -167,3 +195,19 @@ getTargetEmulatorPath(const char* progName, const char* avdArch) APANIC("Missing arch-specific emulator program: %s\n", temp); return NULL; } + +#ifdef _WIN32 +static char* +quotePath(const char* path) +{ + int len = strlen(path); + char* ret = malloc(len+3); + + ret[0] = '"'; + memcpy(ret+1, path, len); + ret[len+1] = '"'; + ret[len+2] = '\0'; + + return ret; +} +#endif /* _WIN32 */ |