diff --git a/kernel/include/kernel/OpenFileDescriptorSet.h b/kernel/include/kernel/OpenFileDescriptorSet.h index df2290dd..857a4995 100644 --- a/kernel/include/kernel/OpenFileDescriptorSet.h +++ b/kernel/include/kernel/OpenFileDescriptorSet.h @@ -23,6 +23,8 @@ namespace Kernel BAN::ErrorOr open(BAN::StringView absolute_path, int flags); + BAN::ErrorOr socket(int domain, int type, int protocol); + BAN::ErrorOr pipe(int fds[2]); BAN::ErrorOr dup(int); diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index aa291498..25742af2 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -111,6 +111,8 @@ namespace Kernel BAN::ErrorOr sys_chmod(const char*, mode_t); BAN::ErrorOr sys_chown(const char*, uid_t, gid_t); + BAN::ErrorOr sys_socket(int domain, int type, int protocol); + BAN::ErrorOr sys_pipe(int fildes[2]); BAN::ErrorOr sys_dup(int fildes); BAN::ErrorOr sys_dup2(int fildes, int fildes2); diff --git a/kernel/kernel/OpenFileDescriptorSet.cpp b/kernel/kernel/OpenFileDescriptorSet.cpp index 083fe222..207ec2b8 100644 --- a/kernel/kernel/OpenFileDescriptorSet.cpp +++ b/kernel/kernel/OpenFileDescriptorSet.cpp @@ -1,8 +1,10 @@ #include #include +#include #include #include +#include namespace Kernel { @@ -76,6 +78,38 @@ namespace Kernel return fd; } + BAN::ErrorOr OpenFileDescriptorSet::socket(int domain, int type, int protocol) + { + using SocketType = NetworkManager::SocketType; + + if (domain != AF_INET) + return BAN::Error::from_errno(EAFNOSUPPORT); + if (protocol != 0) + return BAN::Error::from_errno(EPROTONOSUPPORT); + + SocketType sock_type; + switch (type) + { + case SOCK_STREAM: + sock_type = SocketType::STREAM; + break; + case SOCK_DGRAM: + sock_type = SocketType::DGRAM; + break; + case SOCK_SEQPACKET: + sock_type = SocketType::SEQPACKET; + break; + default: + return BAN::Error::from_errno(EPROTOTYPE); + } + + auto socket = TRY(NetworkManager::get().create_socket(sock_type, 0777, m_credentials.euid(), m_credentials.egid())); + + int fd = TRY(get_free_fd()); + m_open_files[fd] = TRY(BAN::RefPtr::create(socket, "no-path"sv, 0, O_RDWR)); + return fd; + } + BAN::ErrorOr OpenFileDescriptorSet::pipe(int fds[2]) { TRY(get_free_fd_pair(fds)); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 23613d49..607308b4 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -895,6 +895,12 @@ namespace Kernel return 0; } + BAN::ErrorOr Process::sys_socket(int domain, int type, int protocol) + { + LockGuard _(m_lock); + return TRY(m_open_file_descriptors.socket(domain, type, protocol)); + } + BAN::ErrorOr Process::sys_pipe(int fildes[2]) { LockGuard _(m_lock); diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index b61802f6..5a37b4a8 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -213,6 +213,9 @@ namespace Kernel case SYS_LOAD_KEYMAP: ret = Process::current().sys_load_keymap((const char*)arg1); break; + case SYS_SOCKET: + ret = Process::current().sys_socket((int)arg1, (int)arg2, (int)arg3); + break; default: dwarnln("Unknown syscall {}", syscall); break; diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt index 9d42203f..0d3fc235 100644 --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -19,6 +19,7 @@ set(LIBC_SOURCES strings.cpp sys/banan-os.cpp sys/mman.cpp + sys/socket.cpp sys/stat.cpp sys/wait.cpp termios.cpp diff --git a/libc/include/sys/syscall.h b/libc/include/sys/syscall.h index e8971516..584c2fc0 100644 --- a/libc/include/sys/syscall.h +++ b/libc/include/sys/syscall.h @@ -63,6 +63,7 @@ __BEGIN_DECLS #define SYS_PREAD 62 #define SYS_CHOWN 63 #define SYS_LOAD_KEYMAP 64 +#define SYS_SOCKET 65 __END_DECLS diff --git a/libc/sys/socket.cpp b/libc/sys/socket.cpp new file mode 100644 index 00000000..e0e3aed5 --- /dev/null +++ b/libc/sys/socket.cpp @@ -0,0 +1,8 @@ +#include +#include +#include + +int socket(int domain, int type, int protocol) +{ + return syscall(SYS_SOCKET, domain, type, protocol); +}