static _noreturn_ void exec_wrapper(const char *cmd, int argc, char *argv[]) { /* command + NULL + argv */ char *args[argc + 1]; int i; for (i = 0; i < argc; i++) args[i] = argv[i]; args[argc] = NULL; if (cmd[0] == '/') { safe_execv(args[0], args); } else { const char *path = getenv("PATH"); if (!path) errx(EXIT_FAILURE, "command %s not found", cmd); _cleanup_free_ char *buf = strdup(path); char *saveptr = NULL, *segment = strtok_r(buf, ":", &saveptr); for (; segment; segment = strtok_r(NULL, ":", &saveptr)) { char *full_path = joinpath(segment, cmd, NULL); safe_execv(full_path, args); free(full_path); } } errx(EXIT_FAILURE, "command %s not found", cmd); }
static int fs_label(char *devpath, char *volName) { char *labelargs[] = {FS_LABEL_COMMAND, devpath, volName, NULL}; safe_execv(labelargs); return (FSUR_IO_SUCCESS); }
static _noreturn_ void exec_wrapper(int argc, char *argv[]) { /* command + NULL + argv */ const char *exe_path; char *new_argv[argc + 1]; char *cmd = extract_binary(argv[0]); int i; if (cmd) { exe_path = argv[0]; } else { cmd = argv[0]; exe_path = realpath("/proc/self/exe", NULL); if (!exe_path) err(EXIT_FAILURE, "failed to resolve /proc/self/exe"); } new_argv[0] = cmd; for (i = 1; i < argc; i++) new_argv[i] = argv[i]; new_argv[argc] = NULL; if (cmd[0] == '/' || cmd[0] == '.') { safe_execv(cmd, exe_path, new_argv); // If the exec failed, the wrapper was called by its full path cmd = program_invocation_short_name; } exec_from_path(cmd, exe_path, new_argv); }
static int fs_mount(char *devpath, char *mount_point, int removable, int writable, int suid, int dev) { char *kextargs[] = {KEXTLOAD_COMMAND, FS_KEXT_DIR, NULL}; char *mountargs[] = {MOUNT_COMMAND, READWRITE_OPT, "-o", SUID_OPT, "-o", DEV_OPT, "-t", FS_TYPE, devpath, mount_point, NULL}; if (! writable) mountargs[1] = READONLY_OPT; if (! suid) mountargs[3] = NOSUID_OPT; if (! dev) mountargs[5] = NODEV_OPT; if (checkLoadable()) safe_execv(kextargs); /* better here than in mount_udf */ safe_execv(mountargs); ret = FSUR_IO_SUCCESS; return ret; }
static _noreturn_ void exec_from_path(const char *cmd, const char *exe_path, char *argv[]) { char *path = strdup(getenv("PATH")); if (!path) errx(EXIT_FAILURE, "command %s not found", cmd); char *saveptr = NULL, *segment = strtok_r(path, ":", &saveptr); for (; segment; segment = strtok_r(NULL, ":", &saveptr)) { char *full_path = joinpath(segment, cmd, NULL); safe_execv(full_path, exe_path, argv); free(full_path); } errx(EXIT_FAILURE, "command %s not found", cmd); }
int loadsmbvfs() { const char *kextargs[] = {KEXTLOAD_COMMAND, FS_KEXT_DIR, NULL}; int error = 0; /* * temporarily revert to root (required for kextload) */ seteuid(eff_uid); if (!kextisloaded(FULL_KEXTNAME)) { error = safe_execv(kextargs); if (!error) error = !kextisloaded(FULL_KEXTNAME); } seteuid(real_uid); /* and back to real user */ return (error); }
/* Main routine */ int main(int argc, char** argv) { const char* avdName = NULL; char* avdArch = NULL; const char* gpu = NULL; char* emulatorPath; int force_32bit = 0; bool no_window = false; /* Define ANDROID_EMULATOR_DEBUG to 1 in your environment if you want to * see the debug messages from this launcher program. */ const char* debug = getenv("ANDROID_EMULATOR_DEBUG"); if (debug != NULL && *debug && *debug != '0') android_verbose = 1; /* Parse command-line and look for * 1) an avd name either in the form or '-avd <name>' or '@<name>' * 2) '-force-32bit' which always use 32-bit emulator on 64-bit platforms * 3) '-verbose', or '-debug-all' or '-debug all' to enable verbose mode. */ int nn; for (nn = 1; nn < argc; nn++) { const char* opt = argv[nn]; if (!strcmp(opt,"-qemu")) break; if (!strcmp(opt,"-verbose") || !strcmp(opt,"-debug-all")) { android_verbose = 1; } if (!strcmp(opt,"-debug") && nn + 1 < argc && !strcmp(argv[nn + 1], "all")) { android_verbose = 1; } if (!strcmp(opt,"-gpu") && nn + 1 < argc) { gpu = argv[nn + 1]; nn++; } if (!strcmp(opt,"-ranchu")) { ranchu = true; continue; } if (!strcmp(opt,"-force-32bit")) { force_32bit = 1; continue; } if (!strcmp(opt,"-no-window")) { no_window = true; continue; } if (!strcmp(opt,"-list-avds")) { AvdScanner* scanner = avdScanner_new(NULL); for (;;) { const char* name = avdScanner_next(scanner); if (!name) { break; } printf("%s\n", name); } avdScanner_free(scanner); exit(0); } if (!avdName) { if (!strcmp(opt,"-avd") && nn+1 < argc) { avdName = argv[nn+1]; } else if (opt[0] == '@' && opt[1] != '\0') { avdName = opt+1; } } } /* If ANDROID_EMULATOR_FORCE_32BIT is set to 'true' or '1' in the * environment, set -force-32bit automatically. */ { const char kEnvVar[] = "ANDROID_EMULATOR_FORCE_32BIT"; const char* val = getenv(kEnvVar); if (val && (!strcmp(val, "true") || !strcmp(val, "1"))) { if (!force_32bit) { D("Auto-config: -force-32bit (%s=%s)\n", kEnvVar, val); force_32bit = 1; } } } #if defined(__linux__) if (!force_32bit && android_getHostBitness() == 32) { fprintf(stderr, "ERROR: 32-bit Linux Android emulator binaries are DEPRECATED, to use them\n" " you will have to do at least one of the following:\n" "\n" " - Use the '-force-32bit' option when invoking 'emulator'.\n" " - Set ANDROID_EMULATOR_FORCE_32BIT to 'true' in your environment.\n" "\n" " Either one will allow you to use the 32-bit binaries, but please be\n" " aware that these will disappear in a future Android SDK release.\n" " Consider moving to a 64-bit Linux system before that happens.\n" "\n" ); exit(1); } #endif /* If there is an AVD name, we're going to extract its target architecture * by looking at its config.ini */ if (avdName != NULL) { D("Found AVD name '%s'\n", avdName); avdArch = path_getAvdTargetArch(avdName); D("Found AVD target architecture: %s\n", avdArch); } else { /* Otherwise, using the ANDROID_PRODUCT_OUT directory */ const char* androidOut = getenv("ANDROID_PRODUCT_OUT"); if (androidOut != NULL) { D("Found ANDROID_PRODUCT_OUT: %s\n", androidOut); avdArch = path_getBuildTargetArch(androidOut); D("Found build target architecture: %s\n", avdArch ? avdArch : "<NULL>"); } } if (avdArch == NULL) { avdArch = "arm"; D("Can't determine target AVD architecture: defaulting to %s\n", avdArch); } /* Find program directory. */ char* progDir = NULL; path_split(argv[0], &progDir, NULL); /* Only search in current path if there is no directory separator * in |progName|. */ #ifdef _WIN32 bool tryCurrentPath = (!strchr(argv[0], '/') && !strchr(argv[0], '\\')); #else bool tryCurrentPath = !strchr(argv[0], '/'); #endif /* Find the architecture-specific program in the same directory */ bool is_64bit = false; emulatorPath = getTargetEmulatorPath(progDir, tryCurrentPath, avdArch, force_32bit, &is_64bit); D("Found target-specific emulator binary: %s\n", emulatorPath); /* Replace it in our command-line */ argv[0] = emulatorPath; /* We need to find the location of the GLES emulation shared libraries * and modify either LD_LIBRARY_PATH or PATH accordingly */ bool gpuEnabled = false; const char* gpuMode = NULL; if (avdName) { gpuMode = path_getAvdGpuMode(avdName); gpuEnabled = (gpuMode != NULL); } EmuglConfig config; int bitness = is_64bit ? 64 : 32; if (!emuglConfig_init( &config, gpuEnabled, gpuMode, gpu, bitness, no_window)) { fprintf(stderr, "ERROR: %s\n", config.status); exit(1); } D("%s\n", config.status); emuglConfig_setupEnv(&config); /* For Qt-based UI backends, add <lib>/qt/ to the library search path. */ androidQtSetupEnv(is_64bit); #ifdef _WIN32 // Take care of quoting all parameters before sending them to execv(). // See the "Eveyone quotes command line arguments the wrong way" on // MSDN. int n; for (n = 0; n < argc; ++n) { // Technically, this leaks the quoted strings, but we don't care // since this process will terminate after the execv() anyway. argv[n] = win32_cmdline_quote(argv[n]); D("Quoted param: [%s]\n", argv[n]); } #endif if (android_verbose) { int i; printf("emulator: Running :%s\n", emulatorPath); for(i = 0; i < argc; i++) { printf("emulator: qemu backend: argv[%02d] = \"%s\"\n", i, argv[i]); } /* Dump final command-line parameters to make debugging easier */ printf("emulator: Concatenated backend parameters:\n"); for (i = 0; i < argc; i++) { /* To make it easier to copy-paste the output to a command-line, * quote anything that contains spaces. */ if (strchr(argv[i], ' ') != NULL) { printf(" '%s'", argv[i]); } else { printf(" %s", argv[i]); } } printf("\n"); } // Launch it with the same set of options ! // Note that on Windows, the first argument must _not_ be quoted or // Windows will fail to find the program. safe_execv(emulatorPath, argv); /* We could not launch the program ! */ fprintf(stderr, "Could not launch '%s': %s\n", emulatorPath, strerror(errno)); return errno; }
static int fs_unmount(char *devpath) { char *umountargs[] = {UMOUNT_COMMAND, devpath, NULL}; safe_execv(umountargs); return(FSUR_IO_SUCCESS); }
/* Main routine */ int main(int argc, char** argv) { const char* avdName = NULL; char* avdArch = NULL; char* emulatorPath; int force_32bit = 0; /* Define ANDROID_EMULATOR_DEBUG to 1 in your environment if you want to * see the debug messages from this launcher program. */ const char* debug = getenv("ANDROID_EMULATOR_DEBUG"); if (debug != NULL && *debug && *debug != '0') android_verbose = 1; /* Parse command-line and look for * 1) an avd name either in the form or '-avd <name>' or '@<name>' * 2) '-force-32bit' which always use 32-bit emulator on 64-bit platforms */ int nn; for (nn = 1; nn < argc; nn++) { const char* opt = argv[nn]; if (!strcmp(opt,"-qemu")) break; if (!strcmp(opt,"-force-32bit")) { force_32bit = 1; continue; } if (!avdName) { if (!strcmp(opt,"-avd") && nn+1 < argc) { avdName = argv[nn+1]; } else if (opt[0] == '@' && opt[1] != '\0') { avdName = opt+1; } } } /* If there is an AVD name, we're going to extract its target architecture * by looking at its config.ini */ if (avdName != NULL) { D("Found AVD name '%s'\n", avdName); avdArch = path_getAvdTargetArch(avdName); D("Found AVD target architecture: %s\n", avdArch); } else { /* Otherwise, using the ANDROID_PRODUCT_OUT directory */ const char* androidOut = getenv("ANDROID_PRODUCT_OUT"); if (androidOut != NULL && *androidOut != '\0') { D("Found ANDROID_PRODUCT_OUT: %s\n", androidOut); avdArch = path_getBuildTargetArch(androidOut); D("Found build target architecture: %s\n", avdArch); } } if (avdArch == NULL) { avdArch = "arm"; D("Can't determine target AVD architecture: defaulting to %s\n", avdArch); } /* Find the architecture-specific program in the same directory */ emulatorPath = getTargetEmulatorPath(argv[0], avdArch, force_32bit); D("Found target-specific emulator binary: %s\n", emulatorPath); /* 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 /* We need to find the location of the GLES emulation shared libraries * and modify either LD_LIBRARY_PATH or PATH accordingly */ { char* sharedLibPath = getSharedLibraryPath(emulatorPath, GLES_EMULATION_LIB); if (sharedLibPath != NULL) { D("Found OpenGLES emulation libraries in %s\n", sharedLibPath); prependSharedLibraryPath(sharedLibPath); } else { D("Could not find OpenGLES emulation host libraries!\n"); } } /* Launch it with the same set of options ! */ safe_execv(emulatorPath, argv); /* We could not launch the program ! */ fprintf(stderr, "Could not launch '%s': %s\n", emulatorPath, strerror(errno)); return errno; }