aboutsummaryrefslogtreecommitdiffstats
path: root/android
diff options
context:
space:
mode:
authorDavid Turner <digit@android.com>2011-07-15 14:46:26 +0200
committerDavid 'Digit' Turner <digit@android.com>2011-08-04 13:15:47 +0200
commite0b2b39121ec537ff86e7cab045e11a397ed1aca (patch)
tree88dc7335f80e68fe93493dc7017a6e4211be4dfe /android
parente6fffb54a71904ecd0a65f4e9616265326b1aad3 (diff)
downloadexternal_qemu-e0b2b39121ec537ff86e7cab045e11a397ed1aca.zip
external_qemu-e0b2b39121ec537ff86e7cab045e11a397ed1aca.tar.gz
external_qemu-e0b2b39121ec537ff86e7cab045e11a397ed1aca.tar.bz2
Fix Windows space-in-path handling for 'emulator'.
This is a back-port from master to tools_r13 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: Icf66426c88424f2f5d6274a25fc8530ca489f908 Orig-Change-Id: If291c5a8bd507f96b40634ecbc946ba38346ee4e
Diffstat (limited to 'android')
-rw-r--r--android/main-emulator.c48
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 */