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
7namespace mojo {
8
9namespace {
10
11uint64_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
19base::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
29ScopedHandle 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
42MojoResult 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
60ScopedSharedBufferHandle 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
90MojoResult 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