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.
| 7721 | // signals the event, and returns a file descriptor wrapped around the pipe |
| 7722 | // handle. This function is called in the child process only. |
| 7723 | int GetStatusFileDescriptor(unsigned int parent_process_id, |
| 7724 | size_t write_handle_as_size_t, |
| 7725 | size_t event_handle_as_size_t) { |
| 7726 | AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, |
| 7727 | FALSE, // Non-inheritable. |
| 7728 | parent_process_id)); |
| 7729 | if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { |
| 7730 | DeathTestAbort("Unable to open parent process " + |
| 7731 | StreamableToString(parent_process_id)); |
| 7732 | } |
| 7733 | |
| 7734 | // TODO(vladl@google.com): Replace the following check with a |
| 7735 | // compile-time assertion when available. |
| 7736 | GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); |
| 7737 | |
| 7738 | const HANDLE write_handle = |
| 7739 | reinterpret_cast<HANDLE>(write_handle_as_size_t); |
| 7740 | HANDLE dup_write_handle; |
| 7741 | |
| 7742 | // The newly initialized handle is accessible only in in the parent |
| 7743 | // process. To obtain one accessible within the child, we need to use |
| 7744 | // DuplicateHandle. |
| 7745 | if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, |
| 7746 | ::GetCurrentProcess(), &dup_write_handle, |
| 7747 | 0x0, // Requested privileges ignored since |
| 7748 | // DUPLICATE_SAME_ACCESS is used. |
| 7749 | FALSE, // Request non-inheritable handler. |
| 7750 | DUPLICATE_SAME_ACCESS)) { |
| 7751 | DeathTestAbort("Unable to duplicate the pipe handle " + |
| 7752 | StreamableToString(write_handle_as_size_t) + |
| 7753 | " from the parent process " + |
| 7754 | StreamableToString(parent_process_id)); |
| 7755 | } |
| 7756 | |
| 7757 | const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); |
| 7758 | HANDLE dup_event_handle; |
| 7759 | |
| 7760 | if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, |
| 7761 | ::GetCurrentProcess(), &dup_event_handle, |
| 7762 | 0x0, |
| 7763 | FALSE, |
| 7764 | DUPLICATE_SAME_ACCESS)) { |
| 7765 | DeathTestAbort("Unable to duplicate the event handle " + |
| 7766 | StreamableToString(event_handle_as_size_t) + |
| 7767 | " from the parent process " + |
| 7768 | StreamableToString(parent_process_id)); |
| 7769 | } |
| 7770 | |
| 7771 | const int write_fd = |
| 7772 | ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND); |
| 7773 | if (write_fd == -1) { |
| 7774 | DeathTestAbort("Unable to convert pipe handle " + |
| 7775 | StreamableToString(write_handle_as_size_t) + |
| 7776 | " to a file descriptor"); |
| 7777 | } |
| 7778 | |
| 7779 | // Signals the parent that the write end of the pipe has been acquired |
| 7780 | // so the parent can release its own write end. |
no test coverage detected