/* Probe the filesystem to check if an emulator executable named like * <progDir>/<prefix><arch> exists. * * |progDir| is an optional program directory. If NULL, the executable * will be searched in the current directory. * |variant| is an optional variant. If not NULL, then a name like * 'emulator-<variant>-<archSuffix>' will be searched, instead of * 'emulator-<archSuffix>'. * |archSuffix| is an architecture-specific suffix, like "arm", or 'x86" * If |search_for_64bit_emulator| is true, lookup for 64-bit emulator first, * then the 32-bit version. * If |try_current_path|, try to look into the current path if no * executable was found under |progDir|. * On success, returns the path of the executable (string must be freed by * the caller) and sets |*is_64bit| to indicate whether the binary is a * 64-bit executable. On failure, return NULL. */ static char* probeTargetEmulatorPath(const char* progDir, const char* variant, const char* archSuffix, bool search_for_64bit_emulator, bool try_current_path, bool* is_64bit) { char path[PATH_MAX], *pathEnd = path + sizeof(path), *p; static const char kEmulatorPrefix[] = "emulator-"; static const char kEmulator64Prefix[] = "emulator64-"; #ifdef _WIN32 const char kExeExtension[] = ".exe"; #else const char kExeExtension[] = ""; #endif // First search for the 64-bit emulator binary. if (search_for_64bit_emulator) { p = bufprint_emulatorName(path, pathEnd, progDir, kEmulator64Prefix, variant, archSuffix, kExeExtension); D("Probing program: %s\n", path); if (p < pathEnd && path_exists(path)) { *is_64bit = true; return strdup(path); } } // Then for the 32-bit one. p = bufprint_emulatorName(path, pathEnd, progDir, kEmulatorPrefix, variant, archSuffix, kExeExtension); D("Probing program: %s\n", path); if (p < pathEnd && path_exists(path)) { *is_64bit = false; return strdup(path); } // Not found, try in the current path then if (try_current_path) { char* result; if (search_for_64bit_emulator) { p = bufprint_emulatorName(path, pathEnd, NULL, kEmulator64Prefix, variant, archSuffix, kExeExtension); if (p < pathEnd) { D("Probing path for: %s\n", path); result = path_search_exec(path); if (result) { *is_64bit = true; return result; } } } p = bufprint_emulatorName(path, pathEnd, NULL, kEmulatorPrefix, variant, archSuffix, kExeExtension); if (p < pathEnd) { D("Probing path for: %s\n", path); result = path_search_exec(path); if (result) { *is_64bit = false; return result; } } } return NULL; }
/* Find the target-specific emulator binary. This will be something * like <programDir>/emulator-<targetArch>, where <programDir> is * the directory of the current program. */ static char* getTargetEmulatorPath(const char* progName, const char* avdArch, const int force_32bit) { char* progDir; char path[PATH_MAX], *pathEnd=path+sizeof(path), *p; const char* emulatorPrefix = "emulator-"; const char* emulator64Prefix = "emulator64-"; #ifdef _WIN32 const char* exeExt = ".exe"; /* ToDo: currently amd64-mingw32msvc-gcc doesn't work (http://b/issue?id=5949152) which prevents us from generating 64-bit emulator for Windows */ int search_for_64bit_emulator = 0; #else const char* exeExt = ""; int search_for_64bit_emulator = !force_32bit && getHostOSBitness() == 64; #endif /* Get program's directory name in progDir */ path_split(progName, &progDir, NULL); if (search_for_64bit_emulator) { /* Find 64-bit emulator first */ p = bufprint(path, pathEnd, "%s/%s%s%s", progDir, emulator64Prefix, avdArch, exeExt); if (p >= pathEnd) { APANIC("Path too long: %s\n", progName); } if (path_exists(path)) { free(progDir); return strdup(path); } } /* Find 32-bit emulator */ p = bufprint(path, pathEnd, "%s/%s%s%s", progDir, emulatorPrefix, avdArch, exeExt); free(progDir); if (p >= pathEnd) { APANIC("Path too long: %s\n", progName); } if (path_exists(path)) { return strdup(path); } /* Mmm, the file doesn't exist, If there is no slash / backslash * in our path, we're going to try to search it in our path. */ #ifdef _WIN32 if (strchr(progName, '/') == NULL && strchr(progName, '\\') == NULL) { #else if (strchr(progName, '/') == NULL) { #endif if (search_for_64bit_emulator) { p = bufprint(path, pathEnd, "%s%s%s", emulator64Prefix, avdArch, exeExt); if (p < pathEnd) { char* resolved = path_search_exec(path); if (resolved != NULL) return resolved; } } p = bufprint(path, pathEnd, "%s%s%s", emulatorPrefix, avdArch, exeExt); if (p < pathEnd) { char* resolved = path_search_exec(path); if (resolved != NULL) return resolved; } } /* Otherwise, the program is missing */ APANIC("Missing arch-specific emulator program: %s\n", path); return NULL; } /* return 1 iff <path>/<filename> exists */ static int probePathForFile(const char* path, const char* filename) { char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); p = bufprint(temp, end, "%s/%s", path, filename); D("Probing for: %s\n", temp); return (p < end && path_exists(temp)); }