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"
16 # include "ProtocolUtils.h"
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());
47 FileDescriptor
& FileDescriptor::operator=(FileDescriptor
&& aOther
) {
48 if (this != &aOther
) {
49 mHandle
= std::move(aOther
.mHandle
);
54 bool FileDescriptor::IsValid() const { return mHandle
!= nullptr; }
56 FileDescriptor::UniquePlatformHandle
FileDescriptor::ClonePlatformHandle()
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
;
70 FileDescriptor::UniquePlatformHandle
FileDescriptor::Clone(
71 PlatformHandleType aHandle
) {
72 FileDescriptor::PlatformHandleType newHandle
;
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
);
84 return UniqueFileHandle();
86 newHandle
= dup(aHandle
);
88 return UniqueFileHandle(newHandle
);
91 NS_WARNING("Failed to duplicate file handle for current process!");
92 return UniqueFileHandle();
95 void IPDLParamTraits
<FileDescriptor
>::Write(IPC::MessageWriter
* aWriter
,
97 const FileDescriptor
& aParam
) {
98 WriteIPDLParam(aWriter
, aActor
, aParam
.ClonePlatformHandle());
101 bool IPDLParamTraits
<FileDescriptor
>::Read(IPC::MessageReader
* aReader
,
103 FileDescriptor
* aResult
) {
104 UniqueFileHandle handle
;
105 if (!ReadIPDLParam(aReader
, aActor
, &handle
)) {
109 *aResult
= FileDescriptor(std::move(handle
));
110 if (!aResult
->IsValid()) {
111 printf_stderr("IPDL protocol Error: Received an invalid file descriptor\n");
117 } // namespace mozilla