| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "build/build_config.h" |
| #include "ipc/ipc_platform_file.h" |
| |
| #if defined(OS_WIN) |
| #include <windows.h> |
| #elif defined(OS_POSIX) || defined(OS_FUCHSIA) |
| #include <unistd.h> |
| |
| #include "base/posix/eintr_wrapper.h" |
| #endif |
| |
| namespace IPC { |
| |
| #if defined(OS_WIN) |
| PlatformFileForTransit::PlatformFileForTransit() : handle_(nullptr) {} |
| |
| PlatformFileForTransit::PlatformFileForTransit(HANDLE handle) |
| : handle_(handle) {} |
| |
| bool PlatformFileForTransit::operator==( |
| const PlatformFileForTransit& platform_file) const { |
| return handle_ == platform_file.handle_; |
| } |
| |
| bool PlatformFileForTransit::operator!=( |
| const PlatformFileForTransit& platform_file) const { |
| return !(*this == platform_file); |
| } |
| |
| HANDLE PlatformFileForTransit::GetHandle() const { |
| return handle_; |
| } |
| |
| bool PlatformFileForTransit::IsValid() const { |
| return handle_ != nullptr; |
| } |
| |
| #endif // defined(OS_WIN) |
| |
| PlatformFileForTransit GetPlatformFileForTransit(base::PlatformFile handle, |
| bool close_source_handle) { |
| #if defined(OS_WIN) |
| HANDLE raw_handle = INVALID_HANDLE_VALUE; |
| DWORD options = DUPLICATE_SAME_ACCESS; |
| if (close_source_handle) |
| options |= DUPLICATE_CLOSE_SOURCE; |
| if (handle == INVALID_HANDLE_VALUE || |
| !::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(), |
| &raw_handle, 0, FALSE, options)) { |
| return IPC::InvalidPlatformFileForTransit(); |
| } |
| |
| return IPC::PlatformFileForTransit(raw_handle); |
| #elif defined(OS_POSIX) || defined(OS_FUCHSIA) |
| // If asked to close the source, we can simply re-use the source fd instead of |
| // dup()ing and close()ing. |
| // When we're not closing the source, we need to duplicate the handle and take |
| // ownership of that. The reason is that this function is often used to |
| // generate IPC messages, and the handle must remain valid until it's sent to |
| // the other process from the I/O thread. Without the dup, calling code might |
| // close the source handle before the message is sent, creating a race |
| // condition. |
| int fd = close_source_handle ? handle : HANDLE_EINTR(::dup(handle)); |
| return base::FileDescriptor(fd, true); |
| #endif |
| } |
| |
| PlatformFileForTransit TakePlatformFileForTransit(base::File file) { |
| return GetPlatformFileForTransit(file.TakePlatformFile(), true); |
| } |
| |
| } // namespace IPC |