Home | History | Annotate | Download | only in system
      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