commit d7a745b6f8e9c23ff4e621e895aa39f908376345
parent f82e20dac4380c99f50519fdddb90b2af2d6733f
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Sat, 10 Jan 2026 20:17:22 +0000
unix domain listener
Diffstat:
3 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/linux.hpp b/linux.hpp
@@ -238,11 +238,29 @@ struct addr_ref
span<char const> fat_ptr;
};
+struct un_addr
+{
+ explicit un_addr(span<char const> addr)
+ {
+ size_t slen = addr.size();
+ assert(slen <= sizeof(path));
+ slen += sizeof(family);
+ length = slen;
+ char* p = path;
+ for (auto c : addr)
+ *p++ = c;
+ }
+ operator addr_ref() const noexcept { return {.fat_ptr = {(char const*)this, length}}; }
+private:
+ [[maybe_unused]] uint16_t family = 1;
+ [[maybe_unused]] char path[108];
+ uint8_t length;
+};
+
struct in_addr
{
- in_addr(uint16_t port, uint32_t ipv4) noexcept
- : family{2}
- , data{
+ explicit in_addr(uint16_t port, uint32_t ipv4) noexcept
+ : data{
uint8_t((port & 0xFF00) >> 8),
uint8_t((port & 0x00FF) >> 0),
uint8_t((ipv4 & 0xFF00'0000) >> 24),
@@ -254,11 +272,12 @@ struct in_addr
operator addr_ref() const noexcept { return {.fat_ptr = {(char const*)this, sizeof(*this)}}; }
private:
- [[maybe_unused]] uint16_t family;
+ [[maybe_unused]] uint16_t family = 2;
[[maybe_unused]] uint8_t data[14];
};
extern syscall_result<void> bind(file socket, addr_ref addr) noexcept;
extern syscall_result<void> listen(file socket, int backlog) noexcept;
extern syscall_result<file> accept(file socket, void* addr_buf, socklen_t* addr_len) noexcept;
+syscall_result<void> setsockopt(file socket, int level, int option_name, span<char const> value);
extern syscall_result<file> dup(file oldfd, file newfd, int flags = 0) noexcept;
diff --git a/syscalls.h b/syscalls.h
@@ -71,3 +71,7 @@ SYS(accept)
extern dup3
extern_alias _Z3dup4fileS_i
SYS(dup3)
+
+extern setsockopt
+extern_alias _Z10setsockopt4fileii4spanIKcE
+SYS(setsockopt)
diff --git a/unix-listen.cpp b/unix-listen.cpp
@@ -0,0 +1,21 @@
+#include "linux.hpp"
+
+int main(int argc, char* argv[], char* envp[])
+{
+ if (argc <= 2)
+ return 1;
+
+ (void)unlinkat(AT_FDCWD, argv[1], {});
+
+ file sock = *socket(1/*AF_UNIX*/, 1/*SOCK_STREAM*/, 0);
+ un_addr addr{span<char const>{argv[1], c_str{argv[1]}.length()}};
+ *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[2], argv+2, envp);
+}