#pragma once #include "net/Socket.h" #include "thread/Thread.h" #include #include #include #include class UnixSocket : public Socket { public: UnixSocket(); UnixSocket(UnixSocket* peer); bool will_block_if_read() const override { return (m_state == Connected || m_state == Reset) && !m_data.size(); } bool can_read_data() const override { return (m_state == Connected || m_state == Reset) && m_data.size(); } bool can_accept_connections() const override { return !m_listen_queue.is_empty(); } Result send(const u8*, usize, int) override; Result recv(u8*, usize, int) const override; Result bind(struct sockaddr*, socklen_t) override; Result connect(Registers*, int, struct sockaddr*, socklen_t) override; Result> accept(Registers*, int, struct sockaddr**, socklen_t*) override; Result listen(int backlog) override; void did_close() override; void connect_to_peer(UnixSocket* peer); virtual ~UnixSocket(); private: enum State { Inactive, Bound, Listening, Connecting, Connected, Reset, }; State m_state = State::Inactive; UnixSocket* m_peer = nullptr; mutable Buffer m_data; Thread* m_blocked_thread { nullptr }; DynamicCircularQueue m_listen_queue; struct sockaddr_un m_addr = { .sun_family = AF_UNIX, .sun_path = {} }; socklen_t m_addrlen = sizeof(sa_family_t); };