chromium/mojo/core/ipcz_driver/wrapped_platform_handle.cc

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/core/ipcz_driver/wrapped_platform_handle.h"

#include <cstdint>
#include <utility>

#include "base/check.h"
#include "base/files/scoped_file.h"
#include "base/notreached.h"
#include "build/build_config.h"
#include "mojo/public/cpp/platform/platform_handle.h"
#include "third_party/ipcz/include/ipcz/ipcz.h"

#if BUILDFLAG(IS_FUCHSIA)
#include <lib/fdio/fd.h>
#include <lib/zx/handle.h>

#include "base/fuchsia/fuchsia_logging.h"
#endif

#if BUILDFLAG(IS_APPLE)
#include <mach/mach.h>

#include "base/apple/mach_logging.h"
#include "base/apple/scoped_mach_port.h"
#endif

namespace mojo::core::ipcz_driver {

namespace {

// Enumeration for different possible types of PlatformHandles that may be
// wrapped by a WrappedPlatformHandle.
enum class WrapperType : uint32_t {};

// Header for a serialized WrappedPlatformHandle object.
struct IPCZ_ALIGN(8) WrappedPlatformHandleHeader {};
static_assert;

#if BUILDFLAG(IS_FUCHSIA)
PlatformHandle MakeFDTransmissible(base::ScopedFD fd) {
  zx::handle result;
  const zx_status_t status =
      fdio_fd_transfer_or_clone(fd.release(), result.reset_and_get_address());
  if (status != ZX_OK) {
    ZX_DLOG(ERROR, status) << "fdio_fd_transfer_or_clone";
    return {};
  }
  return PlatformHandle(std::move(result));
}

base::ScopedFD RecoverFDFromTransmissible(PlatformHandle handle) {
  base::ScopedFD fd;
  zx_status_t status = fdio_fd_create(handle.ReleaseHandle(),
                                      base::ScopedFD::Receiver(fd).get());
  if (status != ZX_OK) {
    ZX_DLOG(ERROR, status) << "fdio_fd_create";
    return {};
  }
  return fd;
}
#elif BUILDFLAG(IS_APPLE)
extern "C" {
kern_return_t fileport_makeport(int fd, mach_port_t*);
int fileport_makefd(mach_port_t);
}  // extern "C"

PlatformHandle MakeFDTransmissible(base::ScopedFD fd) {
  base::apple::ScopedMachSendRight port;
  kern_return_t kr = fileport_makeport(
      fd.get(), base::apple::ScopedMachSendRight::Receiver(port).get());
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << "fileport_makeport";
    return {};
  }
  return PlatformHandle(std::move(port));
}

base::ScopedFD RecoverFDFromTransmissible(PlatformHandle handle) {
  if (!handle.is_mach_send()) {
    return {};
  }
  return base::ScopedFD(fileport_makefd(handle.GetMachSendRight().get()));
}
#endif

}  // namespace

WrappedPlatformHandle::WrappedPlatformHandle() = default;

WrappedPlatformHandle::WrappedPlatformHandle(PlatformHandle handle)
    :{}

WrappedPlatformHandle::~WrappedPlatformHandle() = default;

void WrappedPlatformHandle::Close() {}

bool WrappedPlatformHandle::IsSerializable() const {}

bool WrappedPlatformHandle::GetSerializedDimensions(Transport& transmitter,
                                                    size_t& num_bytes,
                                                    size_t& num_handles) {}

bool WrappedPlatformHandle::Serialize(Transport& transmitter,
                                      base::span<uint8_t> data,
                                      base::span<PlatformHandle> handles) {}

// static
scoped_refptr<WrappedPlatformHandle> WrappedPlatformHandle::Deserialize(
    base::span<const uint8_t> data,
    base::span<PlatformHandle> handles) {}

}  // namespace mojo::core::ipcz_driver