#include "mojo/public/cpp/platform/platform_handle.h"
#include <tuple>
#include "base/logging.h"
#include "build/build_config.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#include "base/win/scoped_handle.h"
#elif BUILDFLAG(IS_FUCHSIA)
#include <lib/fdio/limits.h>
#include <unistd.h>
#include <zircon/status.h>
#include "base/fuchsia/fuchsia_logging.h"
#elif BUILDFLAG(IS_APPLE)
#include <mach/vm_map.h>
#include "base/apple/mach_logging.h"
#include "base/apple/scoped_mach_port.h"
#endif
#if BUILDFLAG(IS_POSIX)
#include <unistd.h>
#include "base/files/scoped_file.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "base/android/binder.h"
#endif
namespace mojo {
namespace {
#if BUILDFLAG(IS_WIN)
base::win::ScopedHandle CloneHandle(const base::win::ScopedHandle& handle) {
DCHECK(handle.IsValid());
HANDLE dupe;
BOOL result = FALSE;
if (handle.Get() != INVALID_HANDLE_VALUE) {
result = ::DuplicateHandle(::GetCurrentProcess(), handle.Get(),
::GetCurrentProcess(), &dupe, 0, FALSE,
DUPLICATE_SAME_ACCESS);
}
if (!result)
return base::win::ScopedHandle();
DCHECK_NE(dupe, INVALID_HANDLE_VALUE);
return base::win::ScopedHandle(dupe);
}
#elif BUILDFLAG(IS_FUCHSIA)
zx::handle CloneHandle(const zx::handle& handle) {
DCHECK(handle.is_valid());
zx::handle dupe;
zx_status_t result = handle.duplicate(ZX_RIGHT_SAME_RIGHTS, &dupe);
if (result != ZX_OK)
ZX_DLOG(ERROR, result) << "zx_duplicate_handle";
return std::move(dupe);
}
#elif BUILDFLAG(IS_APPLE)
base::apple::ScopedMachSendRight CloneMachPort(
const base::apple::ScopedMachSendRight& mach_port) {
DCHECK(mach_port.is_valid());
kern_return_t kr = mach_port_mod_refs(mach_task_self(), mach_port.get(),
MACH_PORT_RIGHT_SEND, 1);
if (kr != KERN_SUCCESS) {
MACH_DLOG(ERROR, kr) << "mach_port_mod_refs";
return base::apple::ScopedMachSendRight();
}
return base::apple::ScopedMachSendRight(mach_port.get());
}
#endif
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
base::ScopedFD CloneFD(const base::ScopedFD& fd) { … }
#endif
}
PlatformHandle::PlatformHandle() = default;
PlatformHandle::PlatformHandle(PlatformHandle&& other) { … }
#if BUILDFLAG(IS_WIN)
PlatformHandle::PlatformHandle(base::win::ScopedHandle handle)
: type_(Type::kHandle), handle_(std::move(handle)) {}
#elif BUILDFLAG(IS_FUCHSIA)
PlatformHandle::PlatformHandle(zx::handle handle)
: type_(Type::kHandle), handle_(std::move(handle)) {}
#elif BUILDFLAG(IS_APPLE)
PlatformHandle::PlatformHandle(base::apple::ScopedMachSendRight mach_port)
: type_(Type::kMachSend), mach_send_(std::move(mach_port)) {}
PlatformHandle::PlatformHandle(base::apple::ScopedMachReceiveRight mach_port)
: type_(Type::kMachReceive), mach_receive_(std::move(mach_port)) {}
#endif
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
PlatformHandle::PlatformHandle(base::ScopedFD fd)
: … { … }
#endif
#if BUILDFLAG(IS_ANDROID)
PlatformHandle::PlatformHandle(base::android::BinderRef binder)
: type_(Type::kBinder), binder_(std::move(binder)) {}
#endif
PlatformHandle::~PlatformHandle() = default;
PlatformHandle& PlatformHandle::operator=(PlatformHandle&& other) { … }
void PlatformHandle::ToMojoPlatformHandle(PlatformHandle handle,
MojoPlatformHandle* out_handle) { … }
PlatformHandle PlatformHandle::FromMojoPlatformHandle(
const MojoPlatformHandle* handle) { … }
void PlatformHandle::reset() { … }
void PlatformHandle::release() { … }
PlatformHandle PlatformHandle::Clone() const { … }
}