// Copyright 2016 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 "mojo/public/cpp/system/platform_handle.h" #if defined(OS_MACOSX) && !defined(OS_IOS) #include #include "base/mac/mach_logging.h" #endif namespace mojo { namespace { uint64_t PlatformHandleValueFromPlatformFile(base::PlatformFile file) { #if defined(OS_WIN) return reinterpret_cast(file); #else return static_cast(file); #endif } base::PlatformFile PlatformFileFromPlatformHandleValue(uint64_t value) { #if defined(OS_WIN) return reinterpret_cast(value); #else return static_cast(value); #endif } } // namespace ScopedHandle WrapPlatformFile(base::PlatformFile platform_file) { MojoPlatformHandle platform_handle; platform_handle.struct_size = sizeof(MojoPlatformHandle); platform_handle.type = kPlatformFileHandleType; platform_handle.value = PlatformHandleValueFromPlatformFile(platform_file); MojoHandle mojo_handle; MojoResult result = MojoWrapPlatformHandle(&platform_handle, &mojo_handle); CHECK_EQ(result, MOJO_RESULT_OK); return ScopedHandle(Handle(mojo_handle)); } MojoResult UnwrapPlatformFile(ScopedHandle handle, base::PlatformFile* file) { MojoPlatformHandle platform_handle; platform_handle.struct_size = sizeof(MojoPlatformHandle); MojoResult result = MojoUnwrapPlatformHandle(handle.release().value(), &platform_handle); if (result != MOJO_RESULT_OK) return result; if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_INVALID) { *file = base::kInvalidPlatformFile; } else { CHECK_EQ(platform_handle.type, kPlatformFileHandleType); *file = PlatformFileFromPlatformHandleValue(platform_handle.value); } return MOJO_RESULT_OK; } ScopedSharedBufferHandle WrapSharedMemoryHandle( const base::SharedMemoryHandle& memory_handle, size_t size, bool read_only) { #if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS)) if (memory_handle.fd == base::kInvalidPlatformFile) return ScopedSharedBufferHandle(); #else if (!memory_handle.IsValid()) return ScopedSharedBufferHandle(); #endif MojoPlatformHandle platform_handle; platform_handle.struct_size = sizeof(MojoPlatformHandle); platform_handle.type = kPlatformSharedBufferHandleType; #if defined(OS_MACOSX) && !defined(OS_IOS) platform_handle.value = static_cast(memory_handle.GetMemoryObject()); #elif defined(OS_POSIX) platform_handle.value = PlatformHandleValueFromPlatformFile(memory_handle.fd); #elif defined(OS_WIN) platform_handle.value = PlatformHandleValueFromPlatformFile(memory_handle.GetHandle()); #endif MojoPlatformSharedBufferHandleFlags flags = MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_NONE; if (read_only) flags |= MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY; MojoHandle mojo_handle; MojoResult result = MojoWrapPlatformSharedBufferHandle( &platform_handle, size, flags, &mojo_handle); CHECK_EQ(result, MOJO_RESULT_OK); return ScopedSharedBufferHandle(SharedBufferHandle(mojo_handle)); } MojoResult UnwrapSharedMemoryHandle(ScopedSharedBufferHandle handle, base::SharedMemoryHandle* memory_handle, size_t* size, bool* read_only) { if (!handle.is_valid()) return MOJO_RESULT_INVALID_ARGUMENT; MojoPlatformHandle platform_handle; platform_handle.struct_size = sizeof(MojoPlatformHandle); MojoPlatformSharedBufferHandleFlags flags; size_t num_bytes; MojoResult result = MojoUnwrapPlatformSharedBufferHandle( handle.release().value(), &platform_handle, &num_bytes, &flags); if (result != MOJO_RESULT_OK) return result; if (size) *size = num_bytes; if (read_only) *read_only = flags & MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY; #if defined(OS_MACOSX) && !defined(OS_IOS) CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT); *memory_handle = base::SharedMemoryHandle( static_cast(platform_handle.value), num_bytes, base::GetCurrentProcId()); #elif defined(OS_POSIX) CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR); *memory_handle = base::SharedMemoryHandle( static_cast(platform_handle.value), false); #elif defined(OS_WIN) CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE); *memory_handle = base::SharedMemoryHandle( reinterpret_cast(platform_handle.value), base::GetCurrentProcId()); #endif return MOJO_RESULT_OK; } #if defined(OS_MACOSX) && !defined(OS_IOS) ScopedHandle WrapMachPort(mach_port_t port) { kern_return_t kr = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, 1); MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "MachPortAttachmentMac mach_port_mod_refs"; if (kr != KERN_SUCCESS) return ScopedHandle(); MojoPlatformHandle platform_handle; platform_handle.struct_size = sizeof(MojoPlatformHandle); platform_handle.type = MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT; platform_handle.value = static_cast(port); MojoHandle mojo_handle; MojoResult result = MojoWrapPlatformHandle(&platform_handle, &mojo_handle); CHECK_EQ(result, MOJO_RESULT_OK); return ScopedHandle(Handle(mojo_handle)); } MojoResult UnwrapMachPort(ScopedHandle handle, mach_port_t* port) { MojoPlatformHandle platform_handle; platform_handle.struct_size = sizeof(MojoPlatformHandle); MojoResult result = MojoUnwrapPlatformHandle(handle.release().value(), &platform_handle); if (result != MOJO_RESULT_OK) return result; CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT); *port = static_cast(platform_handle.value); return MOJO_RESULT_OK; } #endif // defined(OS_MACOSX) && !defined(OS_IOS) } // namespace mojo