aboutsummaryrefslogtreecommitdiffstats
path: root/android/main-emulator.c
diff options
context:
space:
mode:
authorDavid Turner <digit@android.com>2011-07-15 14:46:26 +0200
committerDavid Turner <digit@android.com>2011-07-15 14:46:26 +0200
commitadd001c9d30ef442e87ee18ec59342929401bd49 (patch)
tree78080d3ea9920958b0143837570006ecb8fa936a /android/main-emulator.c
parent01ced5e66b05c7ce8c446340e8bf8387cdfad356 (diff)
downloadexternal_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.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 */