Bug 1856331 [wpt PR 42276] - [fetch-later] Force sending when BackgroundSync permissi...
[gecko.git] / ipc / glue / FileDescriptor.cpp
blob697de4cc6350e628e8f73cb0dee59cb10be32ac4
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "FileDescriptor.h"
9 #include "mozilla/Assertions.h"
10 #include "mozilla/ipc/IPDLParamTraits.h"
11 #include "mozilla/ipc/ProtocolMessageUtils.h"
12 #include "nsDebug.h"
14 #ifdef XP_WIN
15 # include <windows.h>
16 # include "ProtocolUtils.h"
17 #else // XP_WIN
18 # include <unistd.h>
19 #endif // XP_WIN
21 namespace mozilla {
22 namespace ipc {
24 FileDescriptor::FileDescriptor() = default;
26 FileDescriptor::FileDescriptor(const FileDescriptor& aOther)
27 : mHandle(Clone(aOther.mHandle.get())) {}
29 FileDescriptor::FileDescriptor(FileDescriptor&& aOther)
30 : mHandle(std::move(aOther.mHandle)) {}
32 FileDescriptor::FileDescriptor(PlatformHandleType aHandle)
33 : mHandle(Clone(aHandle)) {}
35 FileDescriptor::FileDescriptor(UniquePlatformHandle&& aHandle)
36 : mHandle(std::move(aHandle)) {}
38 FileDescriptor::~FileDescriptor() = default;
40 FileDescriptor& FileDescriptor::operator=(const FileDescriptor& aOther) {
41 if (this != &aOther) {
42 mHandle = Clone(aOther.mHandle.get());
44 return *this;
47 FileDescriptor& FileDescriptor::operator=(FileDescriptor&& aOther) {
48 if (this != &aOther) {
49 mHandle = std::move(aOther.mHandle);
51 return *this;
54 bool FileDescriptor::IsValid() const { return mHandle != nullptr; }
56 FileDescriptor::UniquePlatformHandle FileDescriptor::ClonePlatformHandle()
57 const {
58 return Clone(mHandle.get());
61 FileDescriptor::UniquePlatformHandle FileDescriptor::TakePlatformHandle() {
62 return UniquePlatformHandle(mHandle.release());
65 bool FileDescriptor::operator==(const FileDescriptor& aOther) const {
66 return mHandle == aOther.mHandle;
69 // static
70 FileDescriptor::UniquePlatformHandle FileDescriptor::Clone(
71 PlatformHandleType aHandle) {
72 FileDescriptor::PlatformHandleType newHandle;
74 #ifdef XP_WIN
75 if (aHandle == INVALID_HANDLE_VALUE || aHandle == nullptr) {
76 return UniqueFileHandle();
78 if (::DuplicateHandle(GetCurrentProcess(), aHandle, GetCurrentProcess(),
79 &newHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
80 return UniqueFileHandle(newHandle);
82 #else // XP_WIN
83 if (aHandle < 0) {
84 return UniqueFileHandle();
86 newHandle = dup(aHandle);
87 if (newHandle >= 0) {
88 return UniqueFileHandle(newHandle);
90 #endif
91 NS_WARNING("Failed to duplicate file handle for current process!");
92 return UniqueFileHandle();
95 void IPDLParamTraits<FileDescriptor>::Write(IPC::MessageWriter* aWriter,
96 IProtocol* aActor,
97 const FileDescriptor& aParam) {
98 WriteIPDLParam(aWriter, aActor, aParam.ClonePlatformHandle());
101 bool IPDLParamTraits<FileDescriptor>::Read(IPC::MessageReader* aReader,
102 IProtocol* aActor,
103 FileDescriptor* aResult) {
104 UniqueFileHandle handle;
105 if (!ReadIPDLParam(aReader, aActor, &handle)) {
106 return false;
109 *aResult = FileDescriptor(std::move(handle));
110 if (!aResult->IsValid()) {
111 printf_stderr("IPDL protocol Error: Received an invalid file descriptor\n");
113 return true;
116 } // namespace ipc
117 } // namespace mozilla