blob: 72ed737b6a8255f5eb217c40103311e0eff422ad [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>
Dale Curtis56733a02017-08-30 06:53:23 +090010
11#include "base/posix/eintr_wrapper.h"
jrg@chromium.org2eb192e2011-11-04 09:14:16 +090012#endif
13
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090014namespace IPC {
15
erikchen9a454c12017-04-29 11:24:36 +090016#if defined(OS_WIN)
17PlatformFileForTransit::PlatformFileForTransit() : handle_(nullptr) {}
18
19PlatformFileForTransit::PlatformFileForTransit(HANDLE handle)
20 : handle_(handle) {}
21
22bool PlatformFileForTransit::operator==(
23 const PlatformFileForTransit& platform_file) const {
24 return handle_ == platform_file.handle_;
25}
26
27bool PlatformFileForTransit::operator!=(
28 const PlatformFileForTransit& platform_file) const {
29 return !(*this == platform_file);
30}
31
32HANDLE PlatformFileForTransit::GetHandle() const {
33 return handle_;
34}
35
36bool PlatformFileForTransit::IsValid() const {
37 return handle_ != nullptr;
38}
39
40#endif // defined(OS_WIN)
41
erikchen556548b2016-04-07 03:51:55 +090042PlatformFileForTransit GetPlatformFileForTransit(base::PlatformFile handle,
43 bool close_source_handle) {
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090044#if defined(OS_WIN)
erikchenb23e3a42016-03-30 07:26:42 +090045 HANDLE raw_handle = INVALID_HANDLE_VALUE;
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090046 DWORD options = DUPLICATE_SAME_ACCESS;
47 if (close_source_handle)
48 options |= DUPLICATE_CLOSE_SOURCE;
jschuh@chromium.org9e1076f2013-05-25 07:36:01 +090049 if (handle == INVALID_HANDLE_VALUE ||
erikchende36fd32016-04-06 03:32:48 +090050 !::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(),
51 &raw_handle, 0, FALSE, options)) {
52 return IPC::InvalidPlatformFileForTransit();
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090053 }
erikchende36fd32016-04-06 03:32:48 +090054
erikchen9a454c12017-04-29 11:24:36 +090055 return IPC::PlatformFileForTransit(raw_handle);
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090056#elif defined(OS_POSIX)
57 // If asked to close the source, we can simply re-use the source fd instead of
58 // dup()ing and close()ing.
59 // When we're not closing the source, we need to duplicate the handle and take
60 // ownership of that. The reason is that this function is often used to
61 // generate IPC messages, and the handle must remain valid until it's sent to
62 // the other process from the I/O thread. Without the dup, calling code might
63 // close the source handle before the message is sent, creating a race
64 // condition.
Dale Curtis56733a02017-08-30 06:53:23 +090065 int fd = close_source_handle ? handle : HANDLE_EINTR(::dup(handle));
erikchende36fd32016-04-06 03:32:48 +090066 return base::FileDescriptor(fd, true);
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090067#else
68 #error Not implemented.
69#endif
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090070}
71
erikchen33f45fa2016-04-08 01:35:11 +090072PlatformFileForTransit TakePlatformFileForTransit(base::File file) {
erikchen556548b2016-04-07 03:51:55 +090073 return GetPlatformFileForTransit(file.TakePlatformFile(), true);
rvargas@chromium.orgf40fe382014-03-06 05:13:49 +090074}
75
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090076} // namespace IPC