liblinux++

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

commit f82e20dac4380c99f50519fdddb90b2af2d6733f
parent c0a85970509d1ab9424cb7d8aaa2ac17956af869
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Sat, 10 Jan 2026 02:03:35 +0000

tcp-listen: Read port number from cmdline.

Diffstat:
Mcat.cpp | 4+++-
Mlinux.hpp | 4+++-
Mtcp-listen.cpp | 84++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 87 insertions(+), 5 deletions(-)

diff --git a/cat.cpp b/cat.cpp @@ -20,7 +20,9 @@ static void cat(file fd) int main(int argc, char* argv[]) { - for (int i = 1; i < argc; ++i) + if (argc <= 1) + cat(stdin); + else for (int i = 1; i < argc; ++i) { auto res = openat(AT_FDCWD, argv[i], 0, O_RDONLY); if (!res) diff --git a/linux.hpp b/linux.hpp @@ -163,9 +163,11 @@ struct c_str return p - str; } + char const* begin() { return str; } + char const* end() { return begin() + length(); } private: - [[maybe_unused]] char const* str; + char const* str; }; [[noreturn]] diff --git a/tcp-listen.cpp b/tcp-listen.cpp @@ -1,11 +1,89 @@ #include "linux.hpp" +struct reader +{ + reader(c_str in) : s{in.begin()} {} + bool peek(char& out) + { + if (peeked) + { + out = buf; + return true; + } + assert(s); + if (not *s) + return false; + out = buf = *s++; + peeked = true; + return true; + } + void pop() + { + assert(peeked); + peeked = false; + } + +private: + char const* s; + bool peeked = false; + char buf; +}; + +bool isdigit(char c) +{ + return '0' <= c and c <= '9'; +} + +bool decimal(reader& r, uint64_t& out) +{ + char c; + if (not r.peek(c)) + return false; + if (not isdigit(c)) + return false; + r.pop(); + uint64_t val = c - '0'; + while (r.peek(c) and isdigit(c)) + { + r.pop(); + val = val * 10 + c - '0'; + } + out = val; + return true; +} + +void test(c_str in, uint64_t expect) +{ + reader r{in}; + uint64_t x; + assert(decimal(r, x)); + assert(x == expect); +} + +#define tst(x) test(#x, x##ull) + int main(int argc, char* argv[], char* envp[]) { - if (argc < 2) + tst(0); + tst(1); + tst(9); + tst(10); + tst(11); + tst(9001); + test("130AAXX1", 130); + tst(18446744073709551615); + + if (argc <= 2) return 1; + reader rdr{argv[1]}; + uint64_t port; + if (not decimal(rdr, port)) + return 2; + if (port > 65535) + return 3; + file sock = *socket(2/*AF_INET*/, 1/*SOCK_STREAM*/, 0/*IPPROTO_IP*/); - in_addr addr{1337, 0/*IN_ADDR_ANY*/}; + in_addr addr{static_cast<uint16_t>(port), 0/*IN_ADDR_ANY*/}; *bind(sock, addr); *listen(sock, 1); socklen_t addr_len = sizeof(addr); @@ -14,5 +92,5 @@ int main(int argc, char* argv[], char* envp[]) *dup(conn, stdout); *close(conn); *close(sock); - *execve(argv[1], argv+1, envp); + *execve(argv[2], argv+2, envp); }