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:
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);
+}