• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PlatformHandleValueFromPlatformFile(base::PlatformFile file)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 
PlatformFileFromPlatformHandleValue(uint64_t value)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 
WrapPlatformFile(base::PlatformFile platform_file)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 
UnwrapPlatformFile(ScopedHandle handle,base::PlatformFile * file)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 
WrapSharedMemoryHandle(const base::SharedMemoryHandle & memory_handle,size_t size,bool read_only)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 
UnwrapSharedMemoryHandle(ScopedSharedBufferHandle handle,base::SharedMemoryHandle * memory_handle,size_t * size,bool * read_only)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)
WrapMachPort(mach_port_t port)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 
UnwrapMachPort(ScopedHandle handle,mach_port_t * port)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