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