tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FileDescriptor.cpp (3245B)


      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/. */
      6 
      7 #include "FileDescriptor.h"
      8 
      9 #include "mozilla/ipc/ProtocolMessageUtils.h"
     10 #include "nsDebug.h"
     11 
     12 #ifdef XP_WIN
     13 #  include <windows.h>
     14 #  include "ProtocolUtils.h"
     15 #else  // XP_WIN
     16 #  include <unistd.h>
     17 #endif  // XP_WIN
     18 
     19 namespace mozilla {
     20 namespace ipc {
     21 
     22 FileDescriptor::FileDescriptor() = default;
     23 
     24 FileDescriptor::FileDescriptor(const FileDescriptor& aOther)
     25    : mHandle(Clone(aOther.mHandle.get())) {}
     26 
     27 FileDescriptor::FileDescriptor(FileDescriptor&& aOther)
     28    : mHandle(std::move(aOther.mHandle)) {}
     29 
     30 FileDescriptor::FileDescriptor(PlatformHandleType aHandle)
     31    : mHandle(Clone(aHandle)) {}
     32 
     33 FileDescriptor::FileDescriptor(UniquePlatformHandle&& aHandle)
     34    : mHandle(std::move(aHandle)) {}
     35 
     36 FileDescriptor::~FileDescriptor() = default;
     37 
     38 FileDescriptor& FileDescriptor::operator=(const FileDescriptor& aOther) {
     39  if (this != &aOther) {
     40    mHandle = Clone(aOther.mHandle.get());
     41  }
     42  return *this;
     43 }
     44 
     45 FileDescriptor& FileDescriptor::operator=(FileDescriptor&& aOther) {
     46  if (this != &aOther) {
     47    mHandle = std::move(aOther.mHandle);
     48  }
     49  return *this;
     50 }
     51 
     52 bool FileDescriptor::IsValid() const { return mHandle != nullptr; }
     53 
     54 FileDescriptor::UniquePlatformHandle FileDescriptor::ClonePlatformHandle()
     55    const {
     56  return Clone(mHandle.get());
     57 }
     58 
     59 FileDescriptor::UniquePlatformHandle FileDescriptor::TakePlatformHandle() {
     60  return UniquePlatformHandle(mHandle.release());
     61 }
     62 
     63 bool FileDescriptor::operator==(const FileDescriptor& aOther) const {
     64  return mHandle == aOther.mHandle;
     65 }
     66 
     67 // static
     68 FileDescriptor::UniquePlatformHandle FileDescriptor::Clone(
     69    PlatformHandleType aHandle) {
     70  FileDescriptor::PlatformHandleType newHandle;
     71 
     72 #ifdef XP_WIN
     73  if (aHandle == INVALID_HANDLE_VALUE || aHandle == nullptr) {
     74    return UniqueFileHandle();
     75  }
     76  if (::DuplicateHandle(GetCurrentProcess(), aHandle, GetCurrentProcess(),
     77                        &newHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
     78    return UniqueFileHandle(newHandle);
     79  }
     80 #else  // XP_WIN
     81  if (aHandle < 0) {
     82    return UniqueFileHandle();
     83  }
     84  newHandle = dup(aHandle);
     85  if (newHandle >= 0) {
     86    return UniqueFileHandle(newHandle);
     87  }
     88 #endif
     89  NS_WARNING("Failed to duplicate file handle for current process!");
     90  return UniqueFileHandle();
     91 }
     92 
     93 }  // namespace ipc
     94 }  // namespace mozilla
     95 
     96 namespace IPC {
     97 
     98 void ParamTraits<mozilla::ipc::FileDescriptor>::Write(
     99    MessageWriter* aWriter, const mozilla::ipc::FileDescriptor& aParam) {
    100  WriteParam(aWriter, aParam.ClonePlatformHandle());
    101 }
    102 
    103 bool ParamTraits<mozilla::ipc::FileDescriptor>::Read(
    104    MessageReader* aReader, mozilla::ipc::FileDescriptor* aResult) {
    105  mozilla::UniqueFileHandle handle;
    106  if (!ReadParam(aReader, &handle)) {
    107    return false;
    108  }
    109 
    110  *aResult = mozilla::ipc::FileDescriptor(std::move(handle));
    111  if (!aResult->IsValid()) {
    112    printf_stderr("IPDL protocol Error: Received an invalid file descriptor\n");
    113  }
    114  return true;
    115 }
    116 
    117 }  // namespace IPC