bool operator == (const CommandInfo& left, const CommandInfo& right) { if (left.uris().size() != right.uris().size()) { return false; } // TODO(vinod): Factor out the comparison for repeated fields. for (int i = 0; i < left.uris().size(); i++) { bool found = false; for (int j = 0; j < right.uris().size(); j++) { if (left.uris().Get(i) == right.uris().Get(j)) { found = true; break; } } if (!found) { return false; } } if (left.arguments().size() != right.arguments().size()) { return false; } // The order of argv is important. for (int i = 0; i < left.arguments().size(); i++) { if (left.arguments().Get(i) != right.arguments().Get(i)) { return false; } } // NOTE: We are not validating CommandInfo::ContainerInfo here // because it is being deprecated in favor of ContainerInfo. // TODO(vinod): Kill the above comment when // CommandInfo::ContainerInfo is removed. return left.environment() == right.environment() && left.value() == right.value() && left.user() == right.user() && left.shell() == right.shell(); }
inline bool operator == (const CommandInfo& left, const CommandInfo& right) { if (left.uris().size() != right.uris().size()) { return false; } for (int i=0; i<left.uris().size(); i++) { bool found = false; for (int j=0; j<right.uris().size(); j++) { if (left.uris().Get(i) == right.uris().Get(j)) { found = true; break; } } if (!found) { return false; } } return left.has_environment() == right.has_environment() && (!left.has_environment() || (left.environment() == right.environment())) && left.value() == right.value(); }
PROCESS_INFORMATION launchTaskWindows( const CommandInfo& command, Option<string>& rootfs) { PROCESS_INFORMATION processInfo; ::ZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION)); STARTUPINFO startupInfo; ::ZeroMemory(&startupInfo, sizeof(STARTUPINFO)); startupInfo.cb = sizeof(STARTUPINFO); string executable; string commandLine = command.value(); if (command.shell()) { // Use Windows shell (`cmd.exe`). Look for it in the system folder. char systemDir[MAX_PATH]; if (!::GetSystemDirectory(systemDir, MAX_PATH)) { // No way to recover from this, safe to exit the process. abort(); } executable = path::join(systemDir, os::Shell::name); // `cmd.exe` needs to be used in conjunction with the `/c` parameter. // For compliance with C-style applications, `cmd.exe` should be passed // as `argv[0]`. // TODO(alexnaparu): Quotes are probably needed after `/c`. commandLine = strings::join(" ", os::Shell::arg0, os::Shell::arg1, commandLine); } else { // Not a shell command, execute as-is. executable = command.value(); // TODO(jieyu): Consider allowing os::stringify_args to take // `command.arguments()` directly. commandLine = os::stringify_args(os::raw::Argv(command.arguments())); } cout << commandLine << endl; // There are many wrappers on `CreateProcess` that are more user-friendly, // but they don't return the PID of the child process. BOOL createProcessResult = ::CreateProcess( executable.empty() ? nullptr : executable.c_str(), // Module to load. (LPSTR) commandLine.c_str(), // Command line. nullptr, // Default security attributes. nullptr, // Default primary thread security attributes. TRUE, // Inherited parent process handles. CREATE_SUSPENDED, // Create suspended so we can wrap in job object. nullptr, // Use parent's environment. nullptr, // Use parent's current directory. &startupInfo, // STARTUPINFO pointer. &processInfo); // PROCESS_INFORMATION pointer. if (!createProcessResult) { ABORT("launchTaskWindows: CreateProcess failed with error code " + GetLastError()); } Try<HANDLE> job = os::create_job(processInfo.dwProcessId); // The job handle is not closed. The job lifetime is equal or lower // than the process lifetime. if (job.isError()) { abort(); } return processInfo; }