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 namespace mojo {
      8 
      9 namespace {
     10 
     11 uint64_t PlatformHandleValueFromPlatformFile(base::PlatformFile file) {
     12 #if defined(OS_WIN)
     13   return reinterpret_cast<uint64_t>(file);
     14 #else
     15   return static_cast<uint64_t>(file);
     16 #endif
     17 }
     18 
     19 base::PlatformFile PlatformFileFromPlatformHandleValue(uint64_t value) {
     20 #if defined(OS_WIN)
     21   return reinterpret_cast<base::PlatformFile>(value);
     22 #else
     23   return static_cast<base::PlatformFile>(value);
     24 #endif
     25 }
     26 
     27 }  // namespace
     28 
     29 ScopedHandle WrapPlatformFile(base::PlatformFile platform_file) {
     30   MojoPlatformHandle platform_handle;
     31   platform_handle.struct_size = sizeof(MojoPlatformHandle);
     32   platform_handle.type = kPlatformFileHandleType;
     33   platform_handle.value = PlatformHandleValueFromPlatformFile(platform_file);
     34 
     35   MojoHandle mojo_handle;
     36   MojoResult result = MojoWrapPlatformHandle(&platform_handle, &mojo_handle);
     37   CHECK_EQ(result, MOJO_RESULT_OK);
     38 
     39   return ScopedHandle(Handle(mojo_handle));
     40 }
     41 
     42 MojoResult UnwrapPlatformFile(ScopedHandle handle, base::PlatformFile* file) {
     43   MojoPlatformHandle platform_handle;
     44   platform_handle.struct_size = sizeof(MojoPlatformHandle);
     45   MojoResult result = MojoUnwrapPlatformHandle(handle.release().value(),
     46                                                &platform_handle);
     47   if (result != MOJO_RESULT_OK)
     48     return result;
     49 
     50   if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_INVALID) {
     51     *file = base::kInvalidPlatformFile;
     52   } else {
     53     CHECK_EQ(platform_handle.type, kPlatformFileHandleType);
     54     *file = PlatformFileFromPlatformHandleValue(platform_handle.value);
     55   }
     56 
     57   return MOJO_RESULT_OK;
     58 }
     59 
     60 ScopedSharedBufferHandle WrapSharedMemoryHandle(
     61     const base::SharedMemoryHandle& memory_handle,
     62     size_t size,
     63     bool read_only) {
     64   MojoPlatformHandle platform_handle;
     65   platform_handle.struct_size = sizeof(MojoPlatformHandle);
     66   platform_handle.type = kPlatformSharedBufferHandleType;
     67 #if defined(OS_MACOSX) && !defined(OS_IOS)
     68   platform_handle.value =
     69       static_cast<uint64_t>(memory_handle.GetMemoryObject());
     70 #elif defined(OS_POSIX)
     71   platform_handle.value = PlatformHandleValueFromPlatformFile(memory_handle.fd);
     72 #elif defined(OS_WIN)
     73   platform_handle.value =
     74       PlatformHandleValueFromPlatformFile(memory_handle.GetHandle());
     75 #endif
     76 
     77   MojoPlatformSharedBufferHandleFlags flags =
     78       MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_NONE;
     79   if (read_only)
     80     flags |= MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY;
     81 
     82   MojoHandle mojo_handle;
     83   MojoResult result = MojoWrapPlatformSharedBufferHandle(
     84       &platform_handle, size, flags, &mojo_handle);
     85   CHECK_EQ(result, MOJO_RESULT_OK);
     86 
     87   return ScopedSharedBufferHandle(SharedBufferHandle(mojo_handle));
     88 }
     89 
     90 MojoResult UnwrapSharedMemoryHandle(ScopedSharedBufferHandle handle,
     91                                     base::SharedMemoryHandle* memory_handle,
     92                                     size_t* size,
     93                                     bool* read_only) {
     94   MojoPlatformHandle platform_handle;
     95   platform_handle.struct_size = sizeof(MojoPlatformHandle);
     96 
     97   MojoPlatformSharedBufferHandleFlags flags;
     98   size_t num_bytes;
     99   MojoResult result = MojoUnwrapPlatformSharedBufferHandle(
    100       handle.release().value(), &platform_handle, &num_bytes, &flags);
    101   if (result != MOJO_RESULT_OK)
    102     return result;
    103 
    104   if (size)
    105     *size = num_bytes;
    106 
    107   if (read_only)
    108     *read_only = flags & MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY;
    109 
    110 #if defined(OS_MACOSX) && !defined(OS_IOS)
    111   CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT);
    112   *memory_handle = base::SharedMemoryHandle(
    113       static_cast<mach_port_t>(platform_handle.value), num_bytes,
    114       base::GetCurrentProcId());
    115 #elif defined(OS_POSIX)
    116   CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR);
    117   *memory_handle = base::SharedMemoryHandle(
    118       static_cast<int>(platform_handle.value), false);
    119 #elif defined(OS_WIN)
    120   CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE);
    121   *memory_handle = base::SharedMemoryHandle(
    122       reinterpret_cast<HANDLE>(platform_handle.value),
    123       base::GetCurrentProcId());
    124 #endif
    125 
    126   return MOJO_RESULT_OK;
    127 }
    128 
    129 }  // namespace mojo
    130