#pragma once #include #include #include #include #include namespace Kernel { class OpenFileDescriptorSet { BAN_NON_COPYABLE(OpenFileDescriptorSet); public: OpenFileDescriptorSet(const Credentials&); ~OpenFileDescriptorSet(); OpenFileDescriptorSet& operator=(OpenFileDescriptorSet&&); BAN::ErrorOr clone_from(const OpenFileDescriptorSet&); BAN::ErrorOr open(VirtualFileSystem::File&&, int flags); BAN::ErrorOr open(BAN::StringView absolute_path, int flags); BAN::ErrorOr socket(int domain, int type, int protocol); BAN::ErrorOr socketpair(int domain, int type, int protocol, int socket_vector[2]); BAN::ErrorOr pipe(int fds[2]); BAN::ErrorOr dup2(int, int); BAN::ErrorOr fcntl(int fd, int cmd, int extra); BAN::ErrorOr seek(int fd, off_t offset, int whence); BAN::ErrorOr tell(int) const; BAN::ErrorOr truncate(int fd, off_t length); BAN::ErrorOr close(int); void close_all(); void close_cloexec(); BAN::ErrorOr read(int fd, BAN::ByteSpan); BAN::ErrorOr write(int fd, BAN::ConstByteSpan); BAN::ErrorOr read_dir_entries(int fd, struct dirent* list, size_t list_len); BAN::ErrorOr recvfrom(int fd, BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len); BAN::ErrorOr sendto(int fd, BAN::ConstByteSpan buffer, const sockaddr* address, socklen_t address_len); BAN::ErrorOr file_of(int) const; BAN::ErrorOr path_of(int) const; BAN::ErrorOr> inode_of(int); BAN::ErrorOr status_flags_of(int) const; private: struct OpenFileDescription : public BAN::RefCounted { OpenFileDescription(VirtualFileSystem::File file, off_t offset, int status_flags) : file(BAN::move(file)) , offset(offset) , status_flags(status_flags) { } VirtualFileSystem::File file; off_t offset { 0 }; int status_flags; friend class BAN::RefPtr; }; struct OpenFile { OpenFile() = default; OpenFile(BAN::RefPtr description, int descriptor_flags) : description(BAN::move(description)) , descriptor_flags(descriptor_flags) { } BAN::RefPtr inode() const { ASSERT(description); return description->file.inode; } BAN::StringView path() const { ASSERT(description); return description->file.canonical_path.sv(); } int& status_flags() { ASSERT(description); return description->status_flags; } const int& status_flags() const { ASSERT(description); return description->status_flags; } off_t& offset() { ASSERT(description); return description->offset; } const off_t& offset() const { ASSERT(description); return description->offset; } BAN::RefPtr description; int descriptor_flags { 0 }; }; BAN::ErrorOr validate_fd(int) const; BAN::ErrorOr get_free_fd() const; BAN::ErrorOr get_free_fd_pair(int fds[2]) const; private: const Credentials& m_credentials; mutable Mutex m_mutex; BAN::Array m_open_files; }; }