diff --git a/Kernel/FileDescriptor.cpp b/Kernel/FileDescriptor.cpp index b88a5f1789..5b9810339b 100644 --- a/Kernel/FileDescriptor.cpp +++ b/Kernel/FileDescriptor.cpp @@ -7,6 +7,7 @@ #include "FIFO.h" #include "TTY.h" #include "MasterPTY.h" +#include RetainPtr FileDescriptor::create(RetainPtr&& inode) { @@ -18,6 +19,11 @@ RetainPtr FileDescriptor::create(RetainPtr&& de return adopt(*new FileDescriptor(move(device))); } +RetainPtr FileDescriptor::create(RetainPtr&& socket) +{ + return adopt(*new FileDescriptor(move(socket))); +} + RetainPtr FileDescriptor::create_pipe_writer(FIFO& fifo) { return adopt(*new FileDescriptor(fifo, FIFO::Writer)); @@ -38,6 +44,11 @@ FileDescriptor::FileDescriptor(RetainPtr&& device) { } +FileDescriptor::FileDescriptor(RetainPtr&& socket) + : m_socket(move(socket)) +{ +} + FileDescriptor::~FileDescriptor() { if (m_device) { diff --git a/Kernel/FileDescriptor.h b/Kernel/FileDescriptor.h index fb08b09790..3a9635cca1 100644 --- a/Kernel/FileDescriptor.h +++ b/Kernel/FileDescriptor.h @@ -11,9 +11,11 @@ class TTY; class MasterPTY; class Process; +class Socket; class FileDescriptor : public Retainable { public: + static RetainPtr create(RetainPtr&&); static RetainPtr create(RetainPtr&&); static RetainPtr create(RetainPtr&&); static RetainPtr create_pipe_writer(FIFO&); @@ -64,6 +66,10 @@ public: dword file_flags() const { return m_file_flags; } void set_file_flags(dword flags) { m_file_flags = flags; } + bool is_socket() const { return m_socket; } + Socket* socket() { return m_socket.ptr(); } + const Socket* socket() const { return m_socket.ptr(); } + bool is_fifo() const { return m_fifo; } FIFO::Direction fifo_direction() { return m_fifo_direction; } @@ -73,6 +79,7 @@ public: private: friend class VFS; + explicit FileDescriptor(RetainPtr&&); explicit FileDescriptor(RetainPtr&&); explicit FileDescriptor(RetainPtr&&); FileDescriptor(FIFO&, FIFO::Direction); @@ -87,6 +94,8 @@ private: bool m_is_blocking { true }; dword m_file_flags { 0 }; + RetainPtr m_socket; + RetainPtr m_fifo; FIFO::Direction m_fifo_direction { FIFO::Neither }; diff --git a/Kernel/LocalSocket.cpp b/Kernel/LocalSocket.cpp new file mode 100644 index 0000000000..1fbf633223 --- /dev/null +++ b/Kernel/LocalSocket.cpp @@ -0,0 +1,19 @@ +#include +#include +#include + +RetainPtr LocalSocket::create(int type) +{ + return adopt(*new LocalSocket(type)); +} + +LocalSocket::LocalSocket(int type) + : Socket(AF_LOCAL, type, 0) +{ + kprintf("%s(%u) LocalSocket{%p} created with type=%u\n", current->name().characters(), current->pid(), type); +} + +LocalSocket::~LocalSocket() +{ +} + diff --git a/Kernel/LocalSocket.h b/Kernel/LocalSocket.h new file mode 100644 index 0000000000..31a62bb28c --- /dev/null +++ b/Kernel/LocalSocket.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +class LocalSocket final : public Socket { +public: + static RetainPtr create(int type); + virtual ~LocalSocket() override; + +private: + explicit LocalSocket(int type); + + DoubleBuffer m_for_client; + DoubleBuffer m_for_server; +}; + diff --git a/Kernel/Makefile b/Kernel/Makefile index 0dfb4f501b..10e8458184 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -32,7 +32,9 @@ KERNEL_OBJS = \ BochsVGADevice.o \ PCI.o \ PS2MouseDevice.o \ - GUIEventDevice.o + GUIEventDevice.o \ + Socket.o \ + LocalSocket.o VFS_OBJS = \ DiskDevice.o \ diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 457d03423d..ea5e791e5b 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -20,6 +20,7 @@ #include "KSyms.h" #include #include +#include #include "MasterPTY.h" #include "elf.h" @@ -2242,3 +2243,41 @@ DisplayInfo Process::set_video_resolution(int width, int height) BochsVGADevice::the().set_resolution(width, height); return info; } + +int Process::sys$socket(int domain, int type, int protocol) +{ + 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; + } + int error; + auto socket = Socket::create(domain, type, protocol, error); + if (!socket) + return error; + auto descriptor = FileDescriptor::create(move(socket)); + m_fds[fd].set(move(descriptor)); + return fd; +} + +int Process::sys$bind(int sockfd, const sockaddr* addr, socklen_t) +{ + return -ENOTIMPL; +} + +int Process::sys$listen(int sockfd, int backlog) +{ + return -ENOTIMPL; +} + +int Process::sys$accept(int sockfd, sockaddr*, socklen_t) +{ + return -ENOTIMPL; +} + +int Process::sys$connect(int sockfd, const sockaddr*, socklen_t) +{ + return -ENOTIMPL; +} diff --git a/Kernel/Process.h b/Kernel/Process.h index 68c2cbc480..addf30fe10 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -218,6 +218,11 @@ public: int sys$rmdir(const char* pathname); int sys$read_tsc(dword* lsw, dword* msw); int sys$chmod(const char* pathname, mode_t); + int sys$socket(int domain, int type, int protocol); + int sys$bind(int sockfd, const sockaddr* addr, socklen_t); + int sys$listen(int sockfd, int backlog); + int sys$accept(int sockfd, sockaddr*, socklen_t); + int sys$connect(int sockfd, const sockaddr*, socklen_t); DisplayInfo set_video_resolution(int width, int height); diff --git a/Kernel/Socket.cpp b/Kernel/Socket.cpp new file mode 100644 index 0000000000..44e11c3753 --- /dev/null +++ b/Kernel/Socket.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +RetainPtr Socket::create(int domain, int type, int protocol, int& error) +{ + (void)protocol; + switch (domain) { + case AF_LOCAL: + return LocalSocket::create(type); + default: + error = EAFNOSUPPORT; + return nullptr; + } +} + +Socket::Socket(int domain, int type, int protocol) + : m_domain(domain) + , m_type(type) + , m_protocol(protocol) +{ +} + +Socket::~Socket() +{ +} + + diff --git a/Kernel/Socket.h b/Kernel/Socket.h new file mode 100644 index 0000000000..c44ca5da21 --- /dev/null +++ b/Kernel/Socket.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +class Socket : public Retainable { +public: + static RetainPtr create(int domain, int type, int protocol, int& error); + virtual ~Socket(); + + int domain() const { return m_domain; } + int type() const { return m_type; } + int protocol() const { return m_protocol; } + +protected: + Socket(int domain, int type, int protocol); + +private: + int m_domain { 0 }; + int m_type { 0 }; + int m_protocol { 0 }; +}; + diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 806a7472d0..11c0964a14 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -74,6 +74,11 @@ __ENUMERATE_SYSCALL(rmdir) \ __ENUMERATE_SYSCALL(chmod) \ __ENUMERATE_SYSCALL(usleep) \ + __ENUMERATE_SYSCALL(socket) \ + __ENUMERATE_SYSCALL(bind) \ + __ENUMERATE_SYSCALL(accept) \ + __ENUMERATE_SYSCALL(listen) \ + __ENUMERATE_SYSCALL(connect) \ #ifdef SERENITY diff --git a/Kernel/UnixTypes.h b/Kernel/UnixTypes.h index 53457a3813..3137234d59 100644 --- a/Kernel/UnixTypes.h +++ b/Kernel/UnixTypes.h @@ -219,6 +219,7 @@ typedef dword nlink_t; typedef dword uid_t; typedef dword gid_t; typedef dword clock_t; +typedef dword socklen_t; struct tms { clock_t tms_utime; @@ -304,3 +305,18 @@ struct pollfd { short events; short revents; }; + +#define AF_UNSPEC 0 +#define AF_LOCAL 1 + +struct sockaddr { + word sa_family; + char sa_data[14]; +}; + +#define UNIX_PATH_MAX 108 + +struct sockaddr_un { + word sun_family; + char sun_path[UNIX_PATH_MAX]; +}; diff --git a/LibC/sys/stat.h b/LibC/sys/stat.h index f5a8980fe5..d337dfc294 100644 --- a/LibC/sys/stat.h +++ b/LibC/sys/stat.h @@ -12,6 +12,7 @@ __BEGIN_DECLS #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) mode_t umask(mode_t); int chmod(const char* pathname, mode_t);