#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Kernel { class FileBackedRegion; class FileSystem; class SharedFileData; class Inode : public BAN::RefCounted { public: struct Mode { enum Mask : mode_t { IXOTH = 0x0001, IWOTH = 0x0002, IROTH = 0x0004, IXGRP = 0x0008, IWGRP = 0x0010, IRGRP = 0x0020, IXUSR = 0x0040, IWUSR = 0x0080, IRUSR = 0x0100, ISVTX = 0x0200, ISGID = 0x0400, ISUID = 0x0800, IFIFO = 0x1000, IFCHR = 0x2000, IFDIR = 0x4000, IFBLK = 0x6000, IFREG = 0x8000, IFLNK = 0xA000, IFSOCK = 0xC000, TYPE_MASK = 0xF000, }; bool ifchr() const { return (mode & Mask::TYPE_MASK) == Mask::IFCHR; } bool ifdir() const { return (mode & Mask::TYPE_MASK) == Mask::IFDIR; } bool ifblk() const { return (mode & Mask::TYPE_MASK) == Mask::IFBLK; } bool ifreg() const { return (mode & Mask::TYPE_MASK) == Mask::IFREG; } bool ififo() const { return (mode & Mask::TYPE_MASK) == Mask::IFIFO; } bool iflnk() const { return (mode & Mask::TYPE_MASK) == Mask::IFLNK; } bool ifsock() const { return (mode & Mask::TYPE_MASK) == Mask::IFSOCK; } mode_t mode; }; public: virtual ~Inode() {} bool can_access(const Credentials&, int) const; bool operator==(const Inode& other) const { return dev() == other.dev() && ino() == other.ino(); } virtual ino_t ino() const = 0; virtual Mode mode() const = 0; virtual nlink_t nlink() const = 0; virtual uid_t uid() const = 0; virtual gid_t gid() const = 0; virtual off_t size() const = 0; virtual timespec atime() const = 0; virtual timespec mtime() const = 0; virtual timespec ctime() const = 0; virtual blksize_t blksize() const = 0; virtual blkcnt_t blocks() const = 0; virtual dev_t dev() const = 0; virtual dev_t rdev() const = 0; virtual bool is_device() const { return false; } virtual bool is_epoll() const { return false; } virtual bool is_pipe() const { return false; } virtual bool is_tty() const { return false; } virtual const FileSystem* filesystem() const = 0; // Directory API BAN::ErrorOr> find_inode(BAN::StringView); BAN::ErrorOr list_next_inodes(off_t, struct dirent* list, size_t list_size); BAN::ErrorOr create_file(BAN::StringView, mode_t, uid_t, gid_t); BAN::ErrorOr create_directory(BAN::StringView, mode_t, uid_t, gid_t); BAN::ErrorOr link_inode(BAN::StringView, BAN::RefPtr); BAN::ErrorOr unlink(BAN::StringView); // Link API BAN::ErrorOr link_target(); BAN::ErrorOr set_link_target(BAN::StringView); // Socket API BAN::ErrorOr accept(sockaddr* address, socklen_t* address_len, int flags); BAN::ErrorOr bind(const sockaddr* address, socklen_t address_len); BAN::ErrorOr connect(const sockaddr* address, socklen_t address_len); BAN::ErrorOr listen(int backlog); BAN::ErrorOr sendto(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len); BAN::ErrorOr recvfrom(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len); BAN::ErrorOr getsockname(sockaddr* address, socklen_t* address_len); BAN::ErrorOr getpeername(sockaddr* address, socklen_t* address_len); // General API BAN::ErrorOr read(off_t, BAN::ByteSpan buffer); BAN::ErrorOr write(off_t, BAN::ConstByteSpan buffer); BAN::ErrorOr truncate(size_t); BAN::ErrorOr chmod(mode_t); BAN::ErrorOr chown(uid_t, gid_t); BAN::ErrorOr utimens(const timespec[2]); BAN::ErrorOr fsync(); // Select/Non blocking API bool can_read() const; bool can_write() const; bool has_error() const; bool has_hungup() const; BAN::ErrorOr ioctl(int request, void* arg); BAN::ErrorOr add_epoll(class Epoll*); void del_epoll(class Epoll*); void epoll_notify(uint32_t event); virtual void on_close(int status_flags) { (void)status_flags; } virtual void on_clone(int status_flags) { (void)status_flags; } protected: // Directory API virtual BAN::ErrorOr> find_inode_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr list_next_inodes_impl(off_t, struct dirent*, size_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr link_inode_impl(BAN::StringView, BAN::RefPtr) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr unlink_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); } // Link API virtual BAN::ErrorOr link_target_impl() { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr set_link_target_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); } // Socket API virtual BAN::ErrorOr accept_impl(sockaddr*, socklen_t*, int) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr connect_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr listen_impl(int) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr bind_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr getsockname_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr getpeername_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); } // General API virtual BAN::ErrorOr read_impl(off_t, BAN::ByteSpan) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr write_impl(off_t, BAN::ConstByteSpan) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr truncate_impl(size_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr chmod_impl(mode_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr chown_impl(uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr utimens_impl(const timespec[2]) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr fsync_impl() = 0; // Select/Non blocking API virtual bool can_read_impl() const = 0; virtual bool can_write_impl() const = 0; virtual bool has_error_impl() const = 0; virtual bool has_hungup_impl() const = 0; virtual BAN::ErrorOr ioctl_impl(int, void*) { return BAN::Error::from_errno(ENOTSUP); } protected: mutable PriorityMutex m_mutex; private: BAN::WeakPtr m_shared_region; Mutex m_epoll_mutex; BAN::LinkedList m_epolls; friend class Epoll; friend class FileBackedRegion; friend class OpenFileDescriptorSet; friend class SharedFileData; friend class TTY; }; }