liblinux++

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

tcp-listen.cpp (1500B)


      1 #include "linux.hpp"
      2 
      3 struct reader
      4 {
      5 	reader(c_str in) : s{in.begin()} {}
      6 	bool peek(char& out)
      7 	{
      8 		if (peeked)
      9 		{
     10 			out = buf;
     11 			return true;
     12 		}
     13 		assert(s);
     14 		if (not *s)
     15 			return false;
     16 		out = buf = *s++;
     17 		peeked = true;
     18 		return true;
     19 	}
     20 	void pop()
     21 	{
     22 		assert(peeked);
     23 		peeked = false;
     24 	}
     25 
     26 private:
     27 	char const* s;
     28 	bool peeked = false;
     29 	char buf;
     30 };
     31 
     32 bool isdigit(char c)
     33 {
     34 	return '0' <= c and c <= '9';
     35 }
     36 
     37 bool decimal(reader& r, uint64_t& out)
     38 {
     39 	char c;
     40 	if (not r.peek(c))
     41 		return false;
     42 	if (not isdigit(c))
     43 		return false;
     44 	r.pop();
     45 	uint64_t val = c - '0';
     46 	while (r.peek(c) and isdigit(c))
     47 	{
     48 		r.pop();
     49 		val = val * 10 + c - '0';
     50 	}
     51 	out = val;
     52 	return true;
     53 }
     54 
     55 void test(c_str in, uint64_t expect)
     56 {
     57 	reader r{in};
     58 	uint64_t x;
     59 	assert(decimal(r, x));
     60 	assert(x == expect);
     61 }
     62 
     63 #define tst(x) test(#x, x##ull)
     64 
     65 int main(int argc, char* argv[], char* envp[])
     66 {
     67 	tst(0);
     68 	tst(1);
     69 	tst(9);
     70 	tst(10);
     71 	tst(11);
     72 	tst(9001);
     73 	test("130AAXX1", 130);
     74 	tst(18446744073709551615);
     75 
     76 	if (argc <= 2)
     77 		return 1;
     78 	reader rdr{argv[1]};
     79 	uint64_t port;
     80 	if (not decimal(rdr, port))
     81 		return 2;
     82 	if (port > 65535)
     83 		return 3;
     84 
     85 	file sock = *socket(2/*AF_INET*/, 1/*SOCK_STREAM*/, 0/*IPPROTO_IP*/);
     86 	in_addr addr{static_cast<uint16_t>(port), 0/*IN_ADDR_ANY*/};
     87 	*bind(sock, addr);
     88 	*listen(sock, 1);
     89 	socklen_t addr_len = sizeof(addr);
     90 	file conn = *accept(sock, &addr, &addr_len);
     91 	*dup(conn, stdin);
     92 	*dup(conn, stdout);
     93 	*close(conn);
     94 	*close(sock);
     95 	*execve(argv[2], argv+2, envp);
     96 }