blob: db5f8e523463731a1c0d03c0a40bdba271d73bb9 [file] [log] [blame]
shenhan@google.com8a6e4992012-06-05 10:54:46 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
avi42ebda42015-12-22 11:39:04 +09005#include "build/build_config.h"
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +09006#include "ipc/ipc_platform_file.h"
7
shenhan@google.com8a6e4992012-06-05 10:54:46 +09008#if defined(OS_POSIX)
jrg@chromium.org2eb192e2011-11-04 09:14:16 +09009#include <unistd.h>
10#endif
11
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090012namespace IPC {
13
erikchen9a454c12017-04-29 11:24:36 +090014#if defined(OS_WIN)
15PlatformFileForTransit::PlatformFileForTransit() : handle_(nullptr) {}
16
17PlatformFileForTransit::PlatformFileForTransit(HANDLE handle)
18 : handle_(handle) {}
19
20bool PlatformFileForTransit::operator==(
21 const PlatformFileForTransit& platform_file) const {
22 return handle_ == platform_file.handle_;
23}
24
25bool PlatformFileForTransit::operator!=(
26 const PlatformFileForTransit& platform_file) const {
27 return !(*this == platform_file);
28}
29
30HANDLE PlatformFileForTransit::GetHandle() const {
31 return handle_;
32}
33
34bool PlatformFileForTransit::IsValid() const {
35 return handle_ != nullptr;
36}
37
38#endif // defined(OS_WIN)
39
erikchen556548b2016-04-07 03:51:55 +090040PlatformFileForTransit GetPlatformFileForTransit(base::PlatformFile handle,
41 bool close_source_handle) {
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090042#if defined(OS_WIN)
erikchenb23e3a42016-03-30 07:26:42 +090043 HANDLE raw_handle = INVALID_HANDLE_VALUE;
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090044 DWORD options = DUPLICATE_SAME_ACCESS;
45 if (close_source_handle)
46 options |= DUPLICATE_CLOSE_SOURCE;
jschuh@chromium.org9e1076f2013-05-25 07:36:01 +090047 if (handle == INVALID_HANDLE_VALUE ||
erikchende36fd32016-04-06 03:32:48 +090048 !::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(),
49 &raw_handle, 0, FALSE, options)) {
50 return IPC::InvalidPlatformFileForTransit();
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090051 }
erikchende36fd32016-04-06 03:32:48 +090052
erikchen9a454c12017-04-29 11:24:36 +090053 return IPC::PlatformFileForTransit(raw_handle);
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090054#elif defined(OS_POSIX)
55 // If asked to close the source, we can simply re-use the source fd instead of
56 // dup()ing and close()ing.
57 // When we're not closing the source, we need to duplicate the handle and take
58 // ownership of that. The reason is that this function is often used to
59 // generate IPC messages, and the handle must remain valid until it's sent to
60 // the other process from the I/O thread. Without the dup, calling code might
61 // close the source handle before the message is sent, creating a race
62 // condition.
63 int fd = close_source_handle ? handle : ::dup(handle);
erikchende36fd32016-04-06 03:32:48 +090064 return base::FileDescriptor(fd, true);
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090065#else
66 #error Not implemented.
67#endif
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090068}
69
erikchen33f45fa2016-04-08 01:35:11 +090070PlatformFileForTransit TakePlatformFileForTransit(base::File file) {
erikchen556548b2016-04-07 03:51:55 +090071 return GetPlatformFileForTransit(file.TakePlatformFile(), true);
rvargas@chromium.orgf40fe382014-03-06 05:13:49 +090072}
73
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090074} // namespace IPC