[go: nahoru, domu]

blob: 55f0d3c50431f029bf52f62b739a703e9a70c737 [file] [log] [blame]
morrita98b7aaa2015-01-26 22:42:541// Copyright (c) 2015 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 "ipc/ipc_message_attachment.h"
6
Ken Rockotfd907632017-09-14 04:23:417#include "base/files/scoped_file.h"
8#include "base/logging.h"
9#include "ipc/ipc_mojo_handle_attachment.h"
10#include "mojo/public/cpp/system/platform_handle.h"
11
Fabrice de Gans-Riberi894661c2018-05-24 18:43:2212#if defined(OS_POSIX) || defined(OS_FUCHSIA)
Ken Rockotfd907632017-09-14 04:23:4113#include "base/posix/eintr_wrapper.h"
14#include "ipc/ipc_platform_file_attachment_posix.h"
15#endif
16
17#if defined(OS_MACOSX) && !defined(OS_IOS)
18#include "ipc/mach_port_attachment_mac.h"
19#endif
20
21#if defined(OS_WIN)
22#include "ipc/handle_attachment_win.h"
23#endif
24
25#if defined(OS_FUCHSIA)
26#include "ipc/handle_attachment_fuchsia.h"
27#endif
28
morrita98b7aaa2015-01-26 22:42:5429namespace IPC {
30
Ken Rockotfd907632017-09-14 04:23:4131namespace {
32
Fabrice de Gans-Riberi894661c2018-05-24 18:43:2233#if defined(OS_POSIX) || defined(OS_FUCHSIA)
Ken Rockotfd907632017-09-14 04:23:4134base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) {
35 return attachment->Owns()
36 ? base::ScopedFD(attachment->TakePlatformFile())
37 : base::ScopedFD(HANDLE_EINTR(dup(attachment->file())));
38}
Fabrice de Gans-Riberi894661c2018-05-24 18:43:2239#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
Ken Rockotfd907632017-09-14 04:23:4140
41} // namespace
42
43MessageAttachment::MessageAttachment() = default;
44
45MessageAttachment::~MessageAttachment() = default;
46
47mojo::ScopedHandle MessageAttachment::TakeMojoHandle() {
48 switch (GetType()) {
49 case Type::MOJO_HANDLE:
50 return static_cast<internal::MojoHandleAttachment*>(this)->TakeHandle();
51
Fabrice de Gans-Riberi894661c2018-05-24 18:43:2252#if defined(OS_POSIX) || defined(OS_FUCHSIA)
Ken Rockotfd907632017-09-14 04:23:4153 case Type::PLATFORM_FILE: {
54 // We dup() the handles in IPC::Message to transmit.
55 // IPC::MessageAttachmentSet has intricate lifetime semantics for FDs, so
56 // just to dup()-and-own them is the safest option.
57 base::ScopedFD file =
58 TakeOrDupFile(static_cast<internal::PlatformFileAttachment*>(this));
59 if (!file.is_valid()) {
60 DPLOG(WARNING) << "Failed to dup FD to transmit.";
61 return mojo::ScopedHandle();
62 }
63 return mojo::WrapPlatformFile(file.release());
64 }
Fabrice de Gans-Riberi894661c2018-05-24 18:43:2265#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
Ken Rockotfd907632017-09-14 04:23:4166
67#if defined(OS_MACOSX) && !defined(OS_IOS)
68 case Type::MACH_PORT: {
69 auto* attachment = static_cast<internal::MachPortAttachmentMac*>(this);
70 MojoPlatformHandle platform_handle = {
71 sizeof(platform_handle), MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT,
72 static_cast<uint64_t>(attachment->get_mach_port())};
73 MojoHandle wrapped_handle;
Ken Rockot88be0452018-05-16 17:31:0474 if (MojoWrapPlatformHandle(&platform_handle, nullptr, &wrapped_handle) !=
Ken Rockotfd907632017-09-14 04:23:4175 MOJO_RESULT_OK) {
76 return mojo::ScopedHandle();
77 }
78 attachment->reset_mach_port_ownership();
79 return mojo::MakeScopedHandle(mojo::Handle(wrapped_handle));
80 }
81#elif defined(OS_FUCHSIA)
82 case Type::FUCHSIA_HANDLE: {
83 auto* attachment = static_cast<internal::HandleAttachmentFuchsia*>(this);
84 MojoPlatformHandle platform_handle = {
85 sizeof(platform_handle), MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE,
86 static_cast<uint64_t>(attachment->Take())};
87 MojoHandle wrapped_handle;
Ken Rockot88be0452018-05-16 17:31:0488 if (MojoWrapPlatformHandle(&platform_handle, nullptr, &wrapped_handle) !=
Ken Rockotfd907632017-09-14 04:23:4189 MOJO_RESULT_OK) {
90 return mojo::ScopedHandle();
91 }
92 return mojo::MakeScopedHandle(mojo::Handle(wrapped_handle));
93 }
94#elif defined(OS_WIN)
95 case Type::WIN_HANDLE:
96 return mojo::WrapPlatformFile(
97 static_cast<internal::HandleAttachmentWin*>(this)->Take());
98#endif
99 default:
100 break;
101 }
102 NOTREACHED();
103 return mojo::ScopedHandle();
morrita1aa788c2015-01-31 05:45:42104}
105
Ken Rockotfd907632017-09-14 04:23:41106// static
107scoped_refptr<MessageAttachment> MessageAttachment::CreateFromMojoHandle(
108 mojo::ScopedHandle handle,
109 Type type) {
110 if (type == Type::MOJO_HANDLE)
111 return new internal::MojoHandleAttachment(std::move(handle));
112
113 MojoPlatformHandle platform_handle = {sizeof(platform_handle), 0, 0};
Ken Rockot88be0452018-05-16 17:31:04114 MojoResult unwrap_result = MojoUnwrapPlatformHandle(
115 handle.release().value(), nullptr, &platform_handle);
Ken Rockotfd907632017-09-14 04:23:41116 if (unwrap_result != MOJO_RESULT_OK)
117 return nullptr;
118
Fabrice de Gans-Riberi894661c2018-05-24 18:43:22119#if defined(OS_POSIX) || defined(OS_FUCHSIA)
Ken Rockotfd907632017-09-14 04:23:41120 if (type == Type::PLATFORM_FILE) {
121 base::PlatformFile file = base::kInvalidPlatformFile;
122 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR)
123 file = static_cast<base::PlatformFile>(platform_handle.value);
124 return new internal::PlatformFileAttachment(file);
125 }
Fabrice de Gans-Riberi894661c2018-05-24 18:43:22126#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
Ken Rockotfd907632017-09-14 04:23:41127
128#if defined(OS_MACOSX) && !defined(OS_IOS)
129 if (type == Type::MACH_PORT) {
130 mach_port_t mach_port = MACH_PORT_NULL;
131 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT)
132 mach_port = static_cast<mach_port_t>(platform_handle.value);
133 return new internal::MachPortAttachmentMac(
134 mach_port, internal::MachPortAttachmentMac::FROM_WIRE);
135 }
136#elif defined(OS_FUCHSIA)
137 if (type == Type::FUCHSIA_HANDLE) {
Wez157707d62018-07-10 22:48:47138 zx::handle handle;
Ken Rockotfd907632017-09-14 04:23:41139 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE)
Scott Grahamfe0e9f462017-09-18 21:25:04140 handle.reset(static_cast<zx_handle_t>(platform_handle.value));
Ken Rockotfd907632017-09-14 04:23:41141 return new internal::HandleAttachmentFuchsia(std::move(handle));
142 }
143#elif defined(OS_WIN)
144 if (type == Type::WIN_HANDLE) {
145 base::PlatformFile handle = base::kInvalidPlatformFile;
146 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE)
147 handle = reinterpret_cast<base::PlatformFile>(platform_handle.value);
148 return new internal::HandleAttachmentWin(
149 handle, internal::HandleAttachmentWin::FROM_WIRE);
150 }
151#endif
152 NOTREACHED();
153 return nullptr;
morrita98b7aaa2015-01-26 22:42:54154}
155
156} // namespace IPC