liblinux++

A hosted C++ runtime without any libc.
git clone git://henryandlizzy.uk/liblinux++
Log | Files | Refs

commit ecbed962c021579f1bdf8f010da7c9de7dae84f4
parent 0dda04fa914c3932d10a52f3517ed51650aa8f64
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Thu,  8 Jan 2026 01:08:23 +0000

add tcp-listen (basic TCP server)

Diffstat:
Mlinux.hpp | 33+++++++++++++++++++++++++++++++++
Msyscalls.h | 20++++++++++++++++++++
Atcp-listen.cpp | 18++++++++++++++++++
3 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/linux.hpp b/linux.hpp @@ -16,6 +16,7 @@ using intptr_t = int64_t; using ino64_t = uint64_t; using off64_t = int64_t; using time_t = int64_t; +using socklen_t = uint32_t; enum { O_RDONLY = 0, @@ -191,6 +192,38 @@ extern syscall_result<void> unlinkat(file dir, c_str path, unlink_flags flags); extern syscall_result<void> execve(c_str path, char *const /*_Nullable*/ argv[], char *const /*_Nullable*/ envp[]); +extern syscall_result<file> socket(int domain, int type, int protocol); + +struct addr_ref +{ + span<char const> fat_ptr; +}; + +struct in_addr +{ + in_addr(uint16_t port, uint32_t ipv4) + : family{2} + , data{ + uint8_t((port & 0xFF00) >> 8), + uint8_t((port & 0x00FF) >> 0), + uint8_t((ipv4 & 0xFF00'0000) >> 24), + uint8_t((ipv4 & 0x00FF'0000) >> 16), + uint8_t((ipv4 & 0x0000'FF00) >> 8), + uint8_t((ipv4 & 0x0000'00FF) >> 0), + } + {} + + operator addr_ref() const { return {.fat_ptr = {(char const*)this, sizeof(*this)}}; } +private: + uint16_t family; + uint8_t data[14]; +}; + +extern syscall_result<void> bind(file socket, addr_ref addr); +extern syscall_result<void> listen(file socket, int backlog); +extern syscall_result<file> accept(file socket, void* addr_buf, socklen_t* addr_len); +extern syscall_result<file> dup(file oldfd, file newfd, int flags = 0); + extern "C" { diff --git a/syscalls.h b/syscalls.h @@ -51,3 +51,23 @@ SYS(mmap) extern renameat2 extern_alias _Z9renameat24file5c_strS_S0_12rename_flags SYS(renameat2) + +extern socket +extern_alias _Z6socketiii +SYS(socket) + +extern bind +extern_alias _Z4bind4file8addr_ref +SYS(bind) + +extern listen +extern_alias _Z6listen4filei +SYS(listen) + +extern accept +extern_alias _Z6accept4filePvPj +SYS(accept) + +extern dup3 +extern_alias _Z3dup4fileS_i +SYS(dup3) diff --git a/tcp-listen.cpp b/tcp-listen.cpp @@ -0,0 +1,18 @@ +#include "linux.hpp" + +int main(int argc, char* argv[], char* envp[]) +{ + if (argc < 2) + return 1; + file sock = *socket(2/*AF_INET*/, 1/*SOCK_STREAM*/, 0/*IPPROTO_IP*/); + in_addr addr{1337, 0/*IN_ADDR_ANY*/}; + *bind(sock, addr); + *listen(sock, 1); + socklen_t addr_len = sizeof(addr); + file conn = *accept(sock, &addr, &addr_len); + *dup(conn, stdin); + *dup(conn, stdout); + *close(conn); + *close(sock); + *execve(argv[1], argv+1, envp); +}