Chromium Code Reviews| Index: runtime/bin/process_win.cc |
| diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc |
| index 860eee09d44d4c42c88ede19e5cf0005abdd4893..ad0156617b40bb0052ddb854105657e78a1b6607 100644 |
| --- a/runtime/bin/process_win.cc |
| +++ b/runtime/bin/process_win.cc |
| @@ -314,6 +314,26 @@ static int SetOsErrorMessage(char** os_error_message) { |
| } |
| +// Open an inheritable handle to NUL. |
| +static HANDLE OpenNul() { |
| + SECURITY_ATTRIBUTES inherit_handle; |
| + inherit_handle.nLength = sizeof(SECURITY_ATTRIBUTES); |
| + inherit_handle.bInheritHandle = TRUE; |
| + inherit_handle.lpSecurityDescriptor = NULL; |
| + HANDLE nul = CreateFile(L"NUL", |
| + GENERIC_READ | GENERIC_WRITE, |
| + 0, |
| + &inherit_handle, |
| + OPEN_EXISTING, |
| + 0, |
| + NULL); |
| + if (nul == INVALID_HANDLE_VALUE) { |
| + Log::PrintErr("CloseHandle failed %d\n", GetLastError()); |
| + } |
| + return nul; |
| +} |
| + |
| + |
| typedef BOOL (WINAPI *InitProcThreadAttrListFn)( |
| LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD, PSIZE_T); |
| @@ -385,6 +405,7 @@ int Process::Start(const char* path, |
| const char* working_directory, |
| char* environment[], |
| intptr_t environment_length, |
| + bool detach, |
| intptr_t* in, |
| intptr_t* out, |
| intptr_t* err, |
| @@ -405,29 +426,56 @@ int Process::Start(const char* path, |
| return status; |
| } |
| - if (!CreateProcessPipe(stdin_handles, pipe_names[0], kInheritRead)) { |
| - int error_code = SetOsErrorMessage(os_error_message); |
| - CloseProcessPipes( |
| - stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| - return error_code; |
| - } |
| - if (!CreateProcessPipe(stdout_handles, pipe_names[1], kInheritWrite)) { |
| - int error_code = SetOsErrorMessage(os_error_message); |
| - CloseProcessPipes( |
| - stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| - return error_code; |
| - } |
| - if (!CreateProcessPipe(stderr_handles, pipe_names[2], kInheritWrite)) { |
| - int error_code = SetOsErrorMessage(os_error_message); |
| - CloseProcessPipes( |
| - stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| - return error_code; |
| - } |
| - if (!CreateProcessPipe(exit_handles, pipe_names[3], kInheritNone)) { |
| - int error_code = SetOsErrorMessage(os_error_message); |
| - CloseProcessPipes( |
| - stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| - return error_code; |
| + if (!detach) { |
| + // Open pipes for stdin, stdout, stderr and for communicating the exit |
| + // code. |
| + if (!CreateProcessPipe(stdin_handles, pipe_names[0], kInheritRead)) { |
| + int error_code = SetOsErrorMessage(os_error_message); |
| + CloseProcessPipes( |
| + stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| + return error_code; |
| + } |
| + if (!CreateProcessPipe(stdout_handles, pipe_names[1], kInheritWrite)) { |
| + int error_code = SetOsErrorMessage(os_error_message); |
| + CloseProcessPipes( |
| + stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| + return error_code; |
| + } |
| + if (!CreateProcessPipe(stderr_handles, pipe_names[2], kInheritWrite)) { |
| + int error_code = SetOsErrorMessage(os_error_message); |
| + CloseProcessPipes( |
| + stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| + return error_code; |
| + } |
| + if (!CreateProcessPipe(exit_handles, pipe_names[3], kInheritNone)) { |
| + int error_code = SetOsErrorMessage(os_error_message); |
| + CloseProcessPipes( |
| + stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| + return error_code; |
| + } |
| + } else { |
| + // Open NUL for stdin, stdout and stderr. |
| + stdin_handles[kReadHandle] = OpenNul(); |
| + if (stdin_handles[kReadHandle] == INVALID_HANDLE_VALUE) { |
| + int error_code = SetOsErrorMessage(os_error_message); |
| + CloseProcessPipes( |
| + stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| + return error_code; |
| + } |
| + stdout_handles[kWriteHandle] = OpenNul(); |
| + if (stdout_handles[kWriteHandle] == INVALID_HANDLE_VALUE) { |
| + int error_code = SetOsErrorMessage(os_error_message); |
| + CloseProcessPipes( |
| + stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| + return error_code; |
| + } |
| + stderr_handles[kWriteHandle] = OpenNul(); |
| + if (stderr_handles[kWriteHandle] == INVALID_HANDLE_VALUE) { |
| + int error_code = SetOsErrorMessage(os_error_message); |
| + CloseProcessPipes( |
| + stdin_handles, stdout_handles, stderr_handles, exit_handles); |
| + return error_code; |
| + } |
|
kustermann
2015/01/22 09:33:02
Do we necessarily need to open "NULL" 3 times in R
Søren Gjesse
2015/01/22 11:47:25
It is, as the new process might close one of these
|
| } |
| // Setup info structures. |
| @@ -582,6 +630,9 @@ int Process::Start(const char* path, |
| // Create process. |
| DWORD creation_flags = |
| EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT; |
| + if (detach) { |
| + creation_flags |= DETACHED_PROCESS; |
| + } |
| BOOL result = CreateProcessW(NULL, // ApplicationName |
| command_line, |
| NULL, // ProcessAttributes |
| @@ -592,7 +643,6 @@ int Process::Start(const char* path, |
| system_working_directory, |
| reinterpret_cast<STARTUPINFOW*>(&startup_info), |
| &process_info); |
| - |
| // Deallocate command-line and environment block strings. |
| delete[] command_line; |
| delete[] environment_block; |
| @@ -612,22 +662,24 @@ int Process::Start(const char* path, |
| return error_code; |
| } |
| - ProcessInfoList::AddProcess(process_info.dwProcessId, |
| - process_info.hProcess, |
| - exit_handles[kWriteHandle]); |
| - |
| - // Connect the three std streams. |
| - FileHandle* stdin_handle = new FileHandle(stdin_handles[kWriteHandle]); |
| CloseHandle(stdin_handles[kReadHandle]); |
| - FileHandle* stdout_handle = new FileHandle(stdout_handles[kReadHandle]); |
| CloseHandle(stdout_handles[kWriteHandle]); |
| - FileHandle* stderr_handle = new FileHandle(stderr_handles[kReadHandle]); |
| CloseHandle(stderr_handles[kWriteHandle]); |
| - FileHandle* exit_handle = new FileHandle(exit_handles[kReadHandle]); |
| - *in = reinterpret_cast<intptr_t>(stdout_handle); |
| - *out = reinterpret_cast<intptr_t>(stdin_handle); |
| - *err = reinterpret_cast<intptr_t>(stderr_handle); |
| - *exit_handler = reinterpret_cast<intptr_t>(exit_handle); |
| + if (!detach) { |
| + ProcessInfoList::AddProcess(process_info.dwProcessId, |
| + process_info.hProcess, |
| + exit_handles[kWriteHandle]); |
| + |
| + // Connect the three std streams. |
| + FileHandle* stdin_handle = new FileHandle(stdin_handles[kWriteHandle]); |
| + FileHandle* stdout_handle = new FileHandle(stdout_handles[kReadHandle]); |
| + FileHandle* stderr_handle = new FileHandle(stderr_handles[kReadHandle]); |
| + FileHandle* exit_handle = new FileHandle(exit_handles[kReadHandle]); |
| + *in = reinterpret_cast<intptr_t>(stdout_handle); |
| + *out = reinterpret_cast<intptr_t>(stdin_handle); |
| + *err = reinterpret_cast<intptr_t>(stderr_handle); |
| + *exit_handler = reinterpret_cast<intptr_t>(exit_handle); |
| + } |
| CloseHandle(process_info.hThread); |
| @@ -833,16 +885,22 @@ bool Process::Wait(intptr_t pid, |
| bool Process::Kill(intptr_t id, int signal) { |
| - USE(signal); // signal is not used on windows. |
| + USE(signal); // signal is not used on Windows. |
| HANDLE process_handle; |
| HANDLE wait_handle; |
| HANDLE exit_pipe; |
| + // First check the process info list for the process to get a handle to it. |
| bool success = ProcessInfoList::LookupProcess(id, |
| &process_handle, |
| &wait_handle, |
| &exit_pipe); |
| - // The process is already dead. |
| - if (!success) return false; |
| + // For detached processes we don't have the process registered in the |
| + // process info list. Try to look it up through the OS. |
| + if (!success) { |
| + process_handle = OpenProcess(PROCESS_TERMINATE, FALSE, id); |
| + // The process is already dead. |
| + if (process_handle == INVALID_HANDLE_VALUE) return false; |
| + } |
| BOOL result = TerminateProcess(process_handle, -1); |
| return result ? true : false; |
|
kustermann
2015/01/22 09:33:02
I'm not really familiar with this code. Will we ge
Søren Gjesse
2015/01/22 11:47:25
On Windows I don't put a detached process in to th
|
| } |