blob: 3a8198e38c1a740642369cf978270c1fc8675b0d [file] [log] [blame]
[email protected]3fcbd4b2012-06-05 01:54:461// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]e7f009d2011-06-14 19:35:102// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
avi246998d82015-12-22 02:39:045#include "build/build_config.h"
[email protected]e7f009d2011-06-14 19:35:106#include "ipc/ipc_platform_file.h"
7
Fabrice de Gans-Ribericbce4342018-05-07 20:02:098#if defined(OS_WIN)
9#include <windows.h>
10#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]6fa21d02011-11-04 00:14:1611#include <unistd.h>
Dale Curtisfdd81dd2017-08-29 21:53:2312
13#include "base/posix/eintr_wrapper.h"
[email protected]6fa21d02011-11-04 00:14:1614#endif
15
[email protected]e7f009d2011-06-14 19:35:1016namespace IPC {
17
erikchend804e1052017-04-29 02:24:3618#if defined(OS_WIN)
19PlatformFileForTransit::PlatformFileForTransit() : handle_(nullptr) {}
20
21PlatformFileForTransit::PlatformFileForTransit(HANDLE handle)
22 : handle_(handle) {}
23
24bool PlatformFileForTransit::operator==(
25 const PlatformFileForTransit& platform_file) const {
26 return handle_ == platform_file.handle_;
27}
28
29bool PlatformFileForTransit::operator!=(
30 const PlatformFileForTransit& platform_file) const {
31 return !(*this == platform_file);
32}
33
34HANDLE PlatformFileForTransit::GetHandle() const {
35 return handle_;
36}
37
38bool PlatformFileForTransit::IsValid() const {
39 return handle_ != nullptr;
40}
41
42#endif // defined(OS_WIN)
43
erikchen09b40032016-04-06 18:51:5544PlatformFileForTransit GetPlatformFileForTransit(base::PlatformFile handle,
45 bool close_source_handle) {
[email protected]e7f009d2011-06-14 19:35:1046#if defined(OS_WIN)
erikchen19e5f692016-03-29 22:26:4247 HANDLE raw_handle = INVALID_HANDLE_VALUE;
[email protected]e7f009d2011-06-14 19:35:1048 DWORD options = DUPLICATE_SAME_ACCESS;
49 if (close_source_handle)
50 options |= DUPLICATE_CLOSE_SOURCE;
[email protected]6f62e3b42013-05-24 22:36:0151 if (handle == INVALID_HANDLE_VALUE ||
erikchen56c6e5d2016-04-05 18:32:4852 !::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(),
53 &raw_handle, 0, FALSE, options)) {
54 return IPC::InvalidPlatformFileForTransit();
[email protected]e7f009d2011-06-14 19:35:1055 }
erikchen56c6e5d2016-04-05 18:32:4856
erikchend804e1052017-04-29 02:24:3657 return IPC::PlatformFileForTransit(raw_handle);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0958#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]e7f009d2011-06-14 19:35:1059 // If asked to close the source, we can simply re-use the source fd instead of
60 // dup()ing and close()ing.
61 // When we're not closing the source, we need to duplicate the handle and take
62 // ownership of that. The reason is that this function is often used to
63 // generate IPC messages, and the handle must remain valid until it's sent to
64 // the other process from the I/O thread. Without the dup, calling code might
65 // close the source handle before the message is sent, creating a race
66 // condition.
Dale Curtisfdd81dd2017-08-29 21:53:2367 int fd = close_source_handle ? handle : HANDLE_EINTR(::dup(handle));
erikchen56c6e5d2016-04-05 18:32:4868 return base::FileDescriptor(fd, true);
[email protected]e7f009d2011-06-14 19:35:1069#endif
[email protected]e7f009d2011-06-14 19:35:1070}
71
erikchen41e60832016-04-07 16:35:1172PlatformFileForTransit TakePlatformFileForTransit(base::File file) {
erikchen09b40032016-04-06 18:51:5573 return GetPlatformFileForTransit(file.TakePlatformFile(), true);
[email protected]8880e702014-03-05 20:13:4974}
75
[email protected]e7f009d2011-06-14 19:35:1076} // namespace IPC