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
PlatformHandleValueFromPlatformFile(base::PlatformFile file)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
PlatformFileFromPlatformHandleValue(uint64_t value)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
WrapPlatformFile(base::PlatformFile platform_file)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
UnwrapPlatformFile(ScopedHandle handle,base::PlatformFile * file)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
WrapSharedMemoryHandle(const base::SharedMemoryHandle & memory_handle,size_t size,bool read_only)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
UnwrapSharedMemoryHandle(ScopedSharedBufferHandle handle,base::SharedMemoryHandle * memory_handle,size_t * size,bool * read_only)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