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