Kernel: Implement fd passing with SCM_RIGTHS

This commit is contained in:
2025-11-09 23:36:49 +02:00
parent 641ccfdd47
commit 7b580b8f56
5 changed files with 186 additions and 35 deletions

View File

@@ -7,6 +7,7 @@
#include <kernel/FS/TmpFS/Inode.h>
#include <kernel/FS/VirtualFileSystem.h>
#include <kernel/Lock/SpinLock.h>
#include <kernel/OpenFileDescriptorSet.h>
namespace Kernel
{
@@ -16,6 +17,9 @@ namespace Kernel
BAN_NON_COPYABLE(UnixDomainSocket);
BAN_NON_MOVABLE(UnixDomainSocket);
public:
using FDWrapper = OpenFileDescriptorSet::FDWrapper;
public:
static BAN::ErrorOr<BAN::RefPtr<UnixDomainSocket>> create(Socket::Type, const Socket::Info&);
BAN::ErrorOr<void> make_socket_pair(UnixDomainSocket&);
@@ -38,7 +42,7 @@ namespace Kernel
UnixDomainSocket(Socket::Type, const Socket::Info&);
~UnixDomainSocket();
BAN::ErrorOr<void> add_packet(const msghdr&, size_t total_size);
BAN::ErrorOr<void> add_packet(const msghdr&, size_t total_size, BAN::Vector<FDWrapper>&& fds_to_send);
bool is_bound() const { return !m_bound_file.canonical_path.empty(); }
bool is_bound_to_unused() const { return !m_bound_file.inode; }
@@ -62,17 +66,23 @@ namespace Kernel
BAN::String peer_address;
};
struct PacketInfo
{
size_t size;
BAN::Vector<FDWrapper> fds;
};
private:
const Socket::Type m_socket_type;
VirtualFileSystem::File m_bound_file;
BAN::Variant<ConnectionInfo, ConnectionlessInfo> m_info;
BAN::CircularQueue<size_t, 128> m_packet_sizes;
size_t m_packet_size_total { 0 };
BAN::UniqPtr<VirtualRange> m_packet_buffer;
Mutex m_packet_lock;
ThreadBlocker m_packet_thread_blocker;
BAN::CircularQueue<PacketInfo, 512> m_packet_infos;
size_t m_packet_size_total { 0 };
BAN::UniqPtr<VirtualRange> m_packet_buffer;
Mutex m_packet_lock;
ThreadBlocker m_packet_thread_blocker;
friend class BAN::RefPtr<UnixDomainSocket>;
};

View File

@@ -109,6 +109,32 @@ namespace Kernel
BAN::ErrorOr<int> get_free_fd() const;
BAN::ErrorOr<void> get_free_fd_pair(int fds[2]) const;
public:
class FDWrapper
{
public:
FDWrapper(BAN::RefPtr<OpenFileDescription>);
FDWrapper(const FDWrapper& other) { *this = other; }
FDWrapper(FDWrapper&& other) { *this = BAN::move(other); }
~FDWrapper();
FDWrapper& operator=(const FDWrapper&);
FDWrapper& operator=(FDWrapper&&);
int fd() const { return m_fd; }
void clear();
private:
BAN::RefPtr<OpenFileDescription> m_description;
int m_fd { -1 };
friend class OpenFileDescriptorSet;
};
BAN::ErrorOr<FDWrapper> get_fd_wrapper(int fd);
size_t open_all_fd_wrappers(BAN::Span<FDWrapper> fd_wrappers);
private:
const Credentials& m_credentials;
mutable Mutex m_mutex;

View File

@@ -240,6 +240,8 @@ namespace Kernel
// FIXME: remove this API
BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const;
OpenFileDescriptorSet& open_file_descriptor_set() { return m_open_file_descriptors; }
// ONLY CALLED BY TIMER INTERRUPT
static void update_alarm_queue();