1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message_attachment.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include "base/files/scoped_file.h"
8*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
9*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_handle_attachment.h"
10*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/platform_handle.h"
11*635a8641SAndroid Build Coastguard Worker
12*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
13*635a8641SAndroid Build Coastguard Worker #include "base/posix/eintr_wrapper.h"
14*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_platform_file_attachment_posix.h"
15*635a8641SAndroid Build Coastguard Worker #endif
16*635a8641SAndroid Build Coastguard Worker
17*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX) && !defined(OS_IOS)
18*635a8641SAndroid Build Coastguard Worker #include "ipc/mach_port_attachment_mac.h"
19*635a8641SAndroid Build Coastguard Worker #endif
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
22*635a8641SAndroid Build Coastguard Worker #include "ipc/handle_attachment_win.h"
23*635a8641SAndroid Build Coastguard Worker #endif
24*635a8641SAndroid Build Coastguard Worker
25*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
26*635a8641SAndroid Build Coastguard Worker #include "ipc/handle_attachment_fuchsia.h"
27*635a8641SAndroid Build Coastguard Worker #endif
28*635a8641SAndroid Build Coastguard Worker
29*635a8641SAndroid Build Coastguard Worker namespace IPC {
30*635a8641SAndroid Build Coastguard Worker
31*635a8641SAndroid Build Coastguard Worker namespace {
32*635a8641SAndroid Build Coastguard Worker
33*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
TakeOrDupFile(internal::PlatformFileAttachment * attachment)34*635a8641SAndroid Build Coastguard Worker base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) {
35*635a8641SAndroid Build Coastguard Worker return attachment->Owns()
36*635a8641SAndroid Build Coastguard Worker ? base::ScopedFD(attachment->TakePlatformFile())
37*635a8641SAndroid Build Coastguard Worker : base::ScopedFD(HANDLE_EINTR(dup(attachment->file())));
38*635a8641SAndroid Build Coastguard Worker }
39*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
40*635a8641SAndroid Build Coastguard Worker
41*635a8641SAndroid Build Coastguard Worker } // namespace
42*635a8641SAndroid Build Coastguard Worker
43*635a8641SAndroid Build Coastguard Worker MessageAttachment::MessageAttachment() = default;
44*635a8641SAndroid Build Coastguard Worker
45*635a8641SAndroid Build Coastguard Worker MessageAttachment::~MessageAttachment() = default;
46*635a8641SAndroid Build Coastguard Worker
TakeMojoHandle()47*635a8641SAndroid Build Coastguard Worker mojo::ScopedHandle MessageAttachment::TakeMojoHandle() {
48*635a8641SAndroid Build Coastguard Worker switch (GetType()) {
49*635a8641SAndroid Build Coastguard Worker case Type::MOJO_HANDLE:
50*635a8641SAndroid Build Coastguard Worker return static_cast<internal::MojoHandleAttachment*>(this)->TakeHandle();
51*635a8641SAndroid Build Coastguard Worker
52*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
53*635a8641SAndroid Build Coastguard Worker case Type::PLATFORM_FILE: {
54*635a8641SAndroid Build Coastguard Worker // We dup() the handles in IPC::Message to transmit.
55*635a8641SAndroid Build Coastguard Worker // IPC::MessageAttachmentSet has intricate lifetime semantics for FDs, so
56*635a8641SAndroid Build Coastguard Worker // just to dup()-and-own them is the safest option.
57*635a8641SAndroid Build Coastguard Worker base::ScopedFD file =
58*635a8641SAndroid Build Coastguard Worker TakeOrDupFile(static_cast<internal::PlatformFileAttachment*>(this));
59*635a8641SAndroid Build Coastguard Worker if (!file.is_valid()) {
60*635a8641SAndroid Build Coastguard Worker DPLOG(WARNING) << "Failed to dup FD to transmit.";
61*635a8641SAndroid Build Coastguard Worker return mojo::ScopedHandle();
62*635a8641SAndroid Build Coastguard Worker }
63*635a8641SAndroid Build Coastguard Worker return mojo::WrapPlatformFile(file.release());
64*635a8641SAndroid Build Coastguard Worker }
65*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
66*635a8641SAndroid Build Coastguard Worker
67*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX) && !defined(OS_IOS)
68*635a8641SAndroid Build Coastguard Worker case Type::MACH_PORT: {
69*635a8641SAndroid Build Coastguard Worker auto* attachment = static_cast<internal::MachPortAttachmentMac*>(this);
70*635a8641SAndroid Build Coastguard Worker MojoPlatformHandle platform_handle = {
71*635a8641SAndroid Build Coastguard Worker sizeof(platform_handle), MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT,
72*635a8641SAndroid Build Coastguard Worker static_cast<uint64_t>(attachment->get_mach_port())};
73*635a8641SAndroid Build Coastguard Worker MojoHandle wrapped_handle;
74*635a8641SAndroid Build Coastguard Worker if (MojoWrapPlatformHandle(&platform_handle, nullptr, &wrapped_handle) !=
75*635a8641SAndroid Build Coastguard Worker MOJO_RESULT_OK) {
76*635a8641SAndroid Build Coastguard Worker return mojo::ScopedHandle();
77*635a8641SAndroid Build Coastguard Worker }
78*635a8641SAndroid Build Coastguard Worker attachment->reset_mach_port_ownership();
79*635a8641SAndroid Build Coastguard Worker return mojo::MakeScopedHandle(mojo::Handle(wrapped_handle));
80*635a8641SAndroid Build Coastguard Worker }
81*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
82*635a8641SAndroid Build Coastguard Worker case Type::FUCHSIA_HANDLE: {
83*635a8641SAndroid Build Coastguard Worker auto* attachment = static_cast<internal::HandleAttachmentFuchsia*>(this);
84*635a8641SAndroid Build Coastguard Worker MojoPlatformHandle platform_handle = {
85*635a8641SAndroid Build Coastguard Worker sizeof(platform_handle), MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE,
86*635a8641SAndroid Build Coastguard Worker static_cast<uint64_t>(attachment->Take())};
87*635a8641SAndroid Build Coastguard Worker MojoHandle wrapped_handle;
88*635a8641SAndroid Build Coastguard Worker if (MojoWrapPlatformHandle(&platform_handle, nullptr, &wrapped_handle) !=
89*635a8641SAndroid Build Coastguard Worker MOJO_RESULT_OK) {
90*635a8641SAndroid Build Coastguard Worker return mojo::ScopedHandle();
91*635a8641SAndroid Build Coastguard Worker }
92*635a8641SAndroid Build Coastguard Worker return mojo::MakeScopedHandle(mojo::Handle(wrapped_handle));
93*635a8641SAndroid Build Coastguard Worker }
94*635a8641SAndroid Build Coastguard Worker #elif defined(OS_WIN)
95*635a8641SAndroid Build Coastguard Worker case Type::WIN_HANDLE:
96*635a8641SAndroid Build Coastguard Worker return mojo::WrapPlatformFile(
97*635a8641SAndroid Build Coastguard Worker static_cast<internal::HandleAttachmentWin*>(this)->Take());
98*635a8641SAndroid Build Coastguard Worker #endif
99*635a8641SAndroid Build Coastguard Worker default:
100*635a8641SAndroid Build Coastguard Worker break;
101*635a8641SAndroid Build Coastguard Worker }
102*635a8641SAndroid Build Coastguard Worker NOTREACHED();
103*635a8641SAndroid Build Coastguard Worker return mojo::ScopedHandle();
104*635a8641SAndroid Build Coastguard Worker }
105*635a8641SAndroid Build Coastguard Worker
106*635a8641SAndroid Build Coastguard Worker // static
CreateFromMojoHandle(mojo::ScopedHandle handle,Type type)107*635a8641SAndroid Build Coastguard Worker scoped_refptr<MessageAttachment> MessageAttachment::CreateFromMojoHandle(
108*635a8641SAndroid Build Coastguard Worker mojo::ScopedHandle handle,
109*635a8641SAndroid Build Coastguard Worker Type type) {
110*635a8641SAndroid Build Coastguard Worker if (type == Type::MOJO_HANDLE)
111*635a8641SAndroid Build Coastguard Worker return new internal::MojoHandleAttachment(std::move(handle));
112*635a8641SAndroid Build Coastguard Worker
113*635a8641SAndroid Build Coastguard Worker MojoPlatformHandle platform_handle = {sizeof(platform_handle), 0, 0};
114*635a8641SAndroid Build Coastguard Worker MojoResult unwrap_result = MojoUnwrapPlatformHandle(
115*635a8641SAndroid Build Coastguard Worker handle.release().value(), nullptr, &platform_handle);
116*635a8641SAndroid Build Coastguard Worker if (unwrap_result != MOJO_RESULT_OK)
117*635a8641SAndroid Build Coastguard Worker return nullptr;
118*635a8641SAndroid Build Coastguard Worker
119*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
120*635a8641SAndroid Build Coastguard Worker if (type == Type::PLATFORM_FILE) {
121*635a8641SAndroid Build Coastguard Worker base::PlatformFile file = base::kInvalidPlatformFile;
122*635a8641SAndroid Build Coastguard Worker if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR)
123*635a8641SAndroid Build Coastguard Worker file = static_cast<base::PlatformFile>(platform_handle.value);
124*635a8641SAndroid Build Coastguard Worker return new internal::PlatformFileAttachment(file);
125*635a8641SAndroid Build Coastguard Worker }
126*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
127*635a8641SAndroid Build Coastguard Worker
128*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX) && !defined(OS_IOS)
129*635a8641SAndroid Build Coastguard Worker if (type == Type::MACH_PORT) {
130*635a8641SAndroid Build Coastguard Worker mach_port_t mach_port = MACH_PORT_NULL;
131*635a8641SAndroid Build Coastguard Worker if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT)
132*635a8641SAndroid Build Coastguard Worker mach_port = static_cast<mach_port_t>(platform_handle.value);
133*635a8641SAndroid Build Coastguard Worker return new internal::MachPortAttachmentMac(
134*635a8641SAndroid Build Coastguard Worker mach_port, internal::MachPortAttachmentMac::FROM_WIRE);
135*635a8641SAndroid Build Coastguard Worker }
136*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
137*635a8641SAndroid Build Coastguard Worker if (type == Type::FUCHSIA_HANDLE) {
138*635a8641SAndroid Build Coastguard Worker zx::handle handle;
139*635a8641SAndroid Build Coastguard Worker if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE)
140*635a8641SAndroid Build Coastguard Worker handle.reset(static_cast<zx_handle_t>(platform_handle.value));
141*635a8641SAndroid Build Coastguard Worker return new internal::HandleAttachmentFuchsia(std::move(handle));
142*635a8641SAndroid Build Coastguard Worker }
143*635a8641SAndroid Build Coastguard Worker #elif defined(OS_WIN)
144*635a8641SAndroid Build Coastguard Worker if (type == Type::WIN_HANDLE) {
145*635a8641SAndroid Build Coastguard Worker base::PlatformFile handle = base::kInvalidPlatformFile;
146*635a8641SAndroid Build Coastguard Worker if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE)
147*635a8641SAndroid Build Coastguard Worker handle = reinterpret_cast<base::PlatformFile>(platform_handle.value);
148*635a8641SAndroid Build Coastguard Worker return new internal::HandleAttachmentWin(
149*635a8641SAndroid Build Coastguard Worker handle, internal::HandleAttachmentWin::FROM_WIRE);
150*635a8641SAndroid Build Coastguard Worker }
151*635a8641SAndroid Build Coastguard Worker #endif
152*635a8641SAndroid Build Coastguard Worker NOTREACHED();
153*635a8641SAndroid Build Coastguard Worker return nullptr;
154*635a8641SAndroid Build Coastguard Worker }
155*635a8641SAndroid Build Coastguard Worker
156*635a8641SAndroid Build Coastguard Worker } // namespace IPC
157