#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 {
enum class WrapperType : uint32_t { … };
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);
}
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
}
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) { … }
scoped_refptr<WrappedPlatformHandle> WrappedPlatformHandle::Deserialize(
base::span<const uint8_t> data,
base::span<PlatformHandle> handles) { … }
}