diff --git a/Kernel/FileDescriptor.cpp b/Kernel/FileDescriptor.cpp index 5b9810339b..06c6f34991 100644 --- a/Kernel/FileDescriptor.cpp +++ b/Kernel/FileDescriptor.cpp @@ -19,9 +19,9 @@ RetainPtr FileDescriptor::create(RetainPtr&& de return adopt(*new FileDescriptor(move(device))); } -RetainPtr FileDescriptor::create(RetainPtr&& socket) +RetainPtr FileDescriptor::create(RetainPtr&& socket, SocketRole role) { - return adopt(*new FileDescriptor(move(socket))); + return adopt(*new FileDescriptor(move(socket), role)); } RetainPtr FileDescriptor::create_pipe_writer(FIFO& fifo) @@ -44,8 +44,9 @@ FileDescriptor::FileDescriptor(RetainPtr&& device) { } -FileDescriptor::FileDescriptor(RetainPtr&& socket) +FileDescriptor::FileDescriptor(RetainPtr&& socket, SocketRole role) : m_socket(move(socket)) + , m_socket_role(role) { } diff --git a/Kernel/FileDescriptor.h b/Kernel/FileDescriptor.h index 3a9635cca1..f89f96f325 100644 --- a/Kernel/FileDescriptor.h +++ b/Kernel/FileDescriptor.h @@ -13,9 +13,12 @@ class MasterPTY; class Process; class Socket; +enum class SocketRole { None, Accepted, Connected }; + class FileDescriptor : public Retainable { public: - static RetainPtr create(RetainPtr&&); + + static RetainPtr create(RetainPtr&&, SocketRole = SocketRole::None); static RetainPtr create(RetainPtr&&); static RetainPtr create(RetainPtr&&); static RetainPtr create_pipe_writer(FIFO&); @@ -79,7 +82,7 @@ public: private: friend class VFS; - explicit FileDescriptor(RetainPtr&&); + FileDescriptor(RetainPtr&&, SocketRole); explicit FileDescriptor(RetainPtr&&); explicit FileDescriptor(RetainPtr&&); FileDescriptor(FIFO&, FIFO::Direction); @@ -95,6 +98,7 @@ private: dword m_file_flags { 0 }; RetainPtr m_socket; + SocketRole m_socket_role { SocketRole::None }; RetainPtr m_fifo; FIFO::Direction m_fifo_direction { FIFO::Neither }; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 549cea4810..2ddf71d6bd 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -2303,6 +2303,13 @@ int Process::sys$accept(int sockfd, sockaddr* address, socklen_t* address_size) return -EFAULT; if (!validate_write(address, *address_size)) return -EFAULT; + if (number_of_open_file_descriptors() >= m_max_open_file_descriptors) + return -EMFILE; + int fd = 0; + for (; fd < (int)m_max_open_file_descriptors; ++fd) { + if (!m_fds[fd]) + break; + } auto* descriptor = file_descriptor(sockfd); if (!descriptor) return -EBADF; @@ -2315,8 +2322,11 @@ int Process::sys$accept(int sockfd, sockaddr* address, socklen_t* address_size) } auto client = socket.accept(); ASSERT(client); - client->get_address(address, address_size); - return 0; + bool success = client->get_address(address, address_size); + ASSERT(success); + auto client_descriptor = FileDescriptor::create(move(client), SocketRole::Accepted); + m_fds[fd].set(move(client_descriptor)); + return fd; } int Process::sys$connect(int sockfd, const sockaddr*, socklen_t)