Recreates the pipe and event handles from the provided parameters, signals the event, and returns a file descriptor wrapped around the pipe handle. This function is called in the child process only.
| 7313 | // signals the event, and returns a file descriptor wrapped around the pipe |
| 7314 | // handle. This function is called in the child process only. |
| 7315 | int GetStatusFileDescriptor(unsigned int parent_process_id, |
| 7316 | size_t write_handle_as_size_t, |
| 7317 | size_t event_handle_as_size_t) { |
| 7318 | AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, |
| 7319 | FALSE, // Non-inheritable. |
| 7320 | parent_process_id)); |
| 7321 | if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { |
| 7322 | DeathTestAbort(String::Format("Unable to open parent process %u", |
| 7323 | parent_process_id)); |
| 7324 | } |
| 7325 | |
| 7326 | // TODO(vladl@google.com): Replace the following check with a |
| 7327 | // compile-time assertion when available. |
| 7328 | GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); |
| 7329 | |
| 7330 | const HANDLE write_handle = |
| 7331 | reinterpret_cast<HANDLE>(write_handle_as_size_t); |
| 7332 | HANDLE dup_write_handle; |
| 7333 | |
| 7334 | // The newly initialized handle is accessible only in in the parent |
| 7335 | // process. To obtain one accessible within the child, we need to use |
| 7336 | // DuplicateHandle. |
| 7337 | if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, |
| 7338 | ::GetCurrentProcess(), &dup_write_handle, |
| 7339 | 0x0, // Requested privileges ignored since |
| 7340 | // DUPLICATE_SAME_ACCESS is used. |
| 7341 | FALSE, // Request non-inheritable handler. |
| 7342 | DUPLICATE_SAME_ACCESS)) { |
| 7343 | DeathTestAbort(String::Format( |
| 7344 | "Unable to duplicate the pipe handle %Iu from the parent process %u", |
| 7345 | write_handle_as_size_t, parent_process_id)); |
| 7346 | } |
| 7347 | |
| 7348 | const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); |
| 7349 | HANDLE dup_event_handle; |
| 7350 | |
| 7351 | if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, |
| 7352 | ::GetCurrentProcess(), &dup_event_handle, |
| 7353 | 0x0, |
| 7354 | FALSE, |
| 7355 | DUPLICATE_SAME_ACCESS)) { |
| 7356 | DeathTestAbort(String::Format( |
| 7357 | "Unable to duplicate the event handle %Iu from the parent process %u", |
| 7358 | event_handle_as_size_t, parent_process_id)); |
| 7359 | } |
| 7360 | |
| 7361 | const int write_fd = |
| 7362 | ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND); |
| 7363 | if (write_fd == -1) { |
| 7364 | DeathTestAbort(String::Format( |
| 7365 | "Unable to convert pipe handle %Iu to a file descriptor", |
| 7366 | write_handle_as_size_t)); |
| 7367 | } |
| 7368 | |
| 7369 | // Signals the parent that the write end of the pipe has been acquired |
| 7370 | // so the parent can release its own write end. |
| 7371 | ::SetEvent(dup_event_handle); |
| 7372 |
no test coverage detected