blob: d8108b3c799f0252da711deee01ec1fe7ec4cc4b [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"
Bruce Dawson052dd802018-01-04 05:32:36 +090012#elif defined(OS_WIN)
13#include <windows.h>
jrg@chromium.org2eb192e2011-11-04 09:14:16 +090014#endif
15
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090016namespace IPC {
17
erikchen9a454c12017-04-29 11:24:36 +090018#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
erikchen556548b2016-04-07 03:51:55 +090044PlatformFileForTransit GetPlatformFileForTransit(base::PlatformFile handle,
45 bool close_source_handle) {
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090046#if defined(OS_WIN)
erikchenb23e3a42016-03-30 07:26:42 +090047 HANDLE raw_handle = INVALID_HANDLE_VALUE;
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090048 DWORD options = DUPLICATE_SAME_ACCESS;
49 if (close_source_handle)
50 options |= DUPLICATE_CLOSE_SOURCE;
jschuh@chromium.org9e1076f2013-05-25 07:36:01 +090051 if (handle == INVALID_HANDLE_VALUE ||
erikchende36fd32016-04-06 03:32:48 +090052 !::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(),
53 &raw_handle, 0, FALSE, options)) {
54 return IPC::InvalidPlatformFileForTransit();
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090055 }
erikchende36fd32016-04-06 03:32:48 +090056
erikchen9a454c12017-04-29 11:24:36 +090057 return IPC::PlatformFileForTransit(raw_handle);
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090058#elif defined(OS_POSIX)
59 // 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 Curtis56733a02017-08-30 06:53:23 +090067 int fd = close_source_handle ? handle : HANDLE_EINTR(::dup(handle));
erikchende36fd32016-04-06 03:32:48 +090068 return base::FileDescriptor(fd, true);
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090069#else
70 #error Not implemented.
71#endif
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090072}
73
erikchen33f45fa2016-04-08 01:35:11 +090074PlatformFileForTransit TakePlatformFileForTransit(base::File file) {
erikchen556548b2016-04-07 03:51:55 +090075 return GetPlatformFileForTransit(file.TakePlatformFile(), true);
rvargas@chromium.orgf40fe382014-03-06 05:13:49 +090076}
77
jcivelli@chromium.org3bab1032011-06-15 04:35:10 +090078} // namespace IPC