1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "mojo/public/cpp/system/platform_handle.h" 6 7 #if defined(OS_MACOSX) && !defined(OS_IOS) 8 #include <mach/mach.h> 9 #include "base/mac/mach_logging.h" 10 #endif 11 12 namespace mojo { 13 14 namespace { 15 16 uint64_t PlatformHandleValueFromPlatformFile(base::PlatformFile file) { 17 #if defined(OS_WIN) 18 return reinterpret_cast<uint64_t>(file); 19 #else 20 return static_cast<uint64_t>(file); 21 #endif 22 } 23 24 base::PlatformFile PlatformFileFromPlatformHandleValue(uint64_t value) { 25 #if defined(OS_WIN) 26 return reinterpret_cast<base::PlatformFile>(value); 27 #else 28 return static_cast<base::PlatformFile>(value); 29 #endif 30 } 31 32 } // namespace 33 34 ScopedHandle WrapPlatformFile(base::PlatformFile platform_file) { 35 MojoPlatformHandle platform_handle; 36 platform_handle.struct_size = sizeof(MojoPlatformHandle); 37 platform_handle.type = kPlatformFileHandleType; 38 platform_handle.value = PlatformHandleValueFromPlatformFile(platform_file); 39 40 MojoHandle mojo_handle; 41 MojoResult result = MojoWrapPlatformHandle(&platform_handle, &mojo_handle); 42 CHECK_EQ(result, MOJO_RESULT_OK); 43 44 return ScopedHandle(Handle(mojo_handle)); 45 } 46 47 MojoResult UnwrapPlatformFile(ScopedHandle handle, base::PlatformFile* file) { 48 MojoPlatformHandle platform_handle; 49 platform_handle.struct_size = sizeof(MojoPlatformHandle); 50 MojoResult result = MojoUnwrapPlatformHandle(handle.release().value(), 51 &platform_handle); 52 if (result != MOJO_RESULT_OK) 53 return result; 54 55 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_INVALID) { 56 *file = base::kInvalidPlatformFile; 57 } else { 58 CHECK_EQ(platform_handle.type, kPlatformFileHandleType); 59 *file = PlatformFileFromPlatformHandleValue(platform_handle.value); 60 } 61 62 return MOJO_RESULT_OK; 63 } 64 65 ScopedSharedBufferHandle WrapSharedMemoryHandle( 66 const base::SharedMemoryHandle& memory_handle, 67 size_t size, 68 bool read_only) { 69 #if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS)) 70 if (memory_handle.fd == base::kInvalidPlatformFile) 71 return ScopedSharedBufferHandle(); 72 #else 73 if (!memory_handle.IsValid()) 74 return ScopedSharedBufferHandle(); 75 #endif 76 MojoPlatformHandle platform_handle; 77 platform_handle.struct_size = sizeof(MojoPlatformHandle); 78 platform_handle.type = kPlatformSharedBufferHandleType; 79 #if defined(OS_MACOSX) && !defined(OS_IOS) 80 platform_handle.value = 81 static_cast<uint64_t>(memory_handle.GetMemoryObject()); 82 #elif defined(OS_POSIX) 83 platform_handle.value = PlatformHandleValueFromPlatformFile(memory_handle.fd); 84 #elif defined(OS_WIN) 85 platform_handle.value = 86 PlatformHandleValueFromPlatformFile(memory_handle.GetHandle()); 87 #endif 88 89 MojoPlatformSharedBufferHandleFlags flags = 90 MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_NONE; 91 if (read_only) 92 flags |= MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY; 93 94 MojoHandle mojo_handle; 95 MojoResult result = MojoWrapPlatformSharedBufferHandle( 96 &platform_handle, size, flags, &mojo_handle); 97 CHECK_EQ(result, MOJO_RESULT_OK); 98 99 return ScopedSharedBufferHandle(SharedBufferHandle(mojo_handle)); 100 } 101 102 MojoResult UnwrapSharedMemoryHandle(ScopedSharedBufferHandle handle, 103 base::SharedMemoryHandle* memory_handle, 104 size_t* size, 105 bool* read_only) { 106 if (!handle.is_valid()) 107 return MOJO_RESULT_INVALID_ARGUMENT; 108 MojoPlatformHandle platform_handle; 109 platform_handle.struct_size = sizeof(MojoPlatformHandle); 110 111 MojoPlatformSharedBufferHandleFlags flags; 112 size_t num_bytes; 113 MojoResult result = MojoUnwrapPlatformSharedBufferHandle( 114 handle.release().value(), &platform_handle, &num_bytes, &flags); 115 if (result != MOJO_RESULT_OK) 116 return result; 117 118 if (size) 119 *size = num_bytes; 120 121 if (read_only) 122 *read_only = flags & MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY; 123 124 #if defined(OS_MACOSX) && !defined(OS_IOS) 125 CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT); 126 *memory_handle = base::SharedMemoryHandle( 127 static_cast<mach_port_t>(platform_handle.value), num_bytes, 128 base::GetCurrentProcId()); 129 #elif defined(OS_POSIX) 130 CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR); 131 *memory_handle = base::SharedMemoryHandle( 132 static_cast<int>(platform_handle.value), false); 133 #elif defined(OS_WIN) 134 CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE); 135 *memory_handle = base::SharedMemoryHandle( 136 reinterpret_cast<HANDLE>(platform_handle.value), 137 base::GetCurrentProcId()); 138 #endif 139 140 return MOJO_RESULT_OK; 141 } 142 143 #if defined(OS_MACOSX) && !defined(OS_IOS) 144 ScopedHandle WrapMachPort(mach_port_t port) { 145 kern_return_t kr = 146 mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, 1); 147 MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) 148 << "MachPortAttachmentMac mach_port_mod_refs"; 149 if (kr != KERN_SUCCESS) 150 return ScopedHandle(); 151 152 MojoPlatformHandle platform_handle; 153 platform_handle.struct_size = sizeof(MojoPlatformHandle); 154 platform_handle.type = MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT; 155 platform_handle.value = static_cast<uint64_t>(port); 156 157 MojoHandle mojo_handle; 158 MojoResult result = MojoWrapPlatformHandle(&platform_handle, &mojo_handle); 159 CHECK_EQ(result, MOJO_RESULT_OK); 160 161 return ScopedHandle(Handle(mojo_handle)); 162 } 163 164 MojoResult UnwrapMachPort(ScopedHandle handle, mach_port_t* port) { 165 MojoPlatformHandle platform_handle; 166 platform_handle.struct_size = sizeof(MojoPlatformHandle); 167 MojoResult result = 168 MojoUnwrapPlatformHandle(handle.release().value(), &platform_handle); 169 if (result != MOJO_RESULT_OK) 170 return result; 171 172 CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT); 173 *port = static_cast<mach_port_t>(platform_handle.value); 174 return MOJO_RESULT_OK; 175 } 176 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 177 178 } // namespace mojo 179