You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.4 KiB
76 lines
2.4 KiB
// 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
|
|
|