xref: /aosp_15_r20/external/libchrome/ipc/ipc_message_attachment.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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