/* * Copyright (c) 2020, Sergey Bugaev * Copyright (c) 2021, Andreas Kling * Copyright (c) 2023-2025, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include namespace IPC { File File::adopt_file(NonnullOwnPtr file) { return File(file->leak_fd()); } File File::adopt_fd(int fd) { return File(fd); } ErrorOr File::clone_fd(int fd) { int new_fd = TRY(Core::System::dup(fd)); return File(new_fd); } File::File(int fd) : m_fd(fd) { } File::File(File&& other) : m_fd(exchange(other.m_fd, -1)) { } File& File::operator=(File&& other) { if (this != &other) { m_fd = exchange(other.m_fd, -1); } return *this; } File::~File() { if (m_fd != -1) (void)Core::System::close(m_fd); } // FIXME: IPC::Files transferred over the wire always set O_CLOEXEC during decoding. Perhaps we should add an option to // allow the receiver to decide whether to make it O_CLOEXEC or not. Or an attribute in the .ipc file? ErrorOr File::clear_close_on_exec() { return Core::System::set_close_on_exec(m_fd, false); } template<> ErrorOr decode(Decoder& decoder) { auto attachment = TRY(decoder.attachments().try_dequeue()); int fd = attachment.to_fd(); if (fd < 0) return Error::from_string_literal("Failed to obtain fd from attachment"); #ifndef AK_OS_WINDOWS TRY(Core::System::set_close_on_exec(fd, true)); #endif return File::adopt_fd(fd); } }