beterraba

commit 5c4c16a894c398a72ffe3b4b7b44d8f0d44ab45d

Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>

server: accept client connections

 cmd/beterrabad/main.ha | 6 ++--
 cmd/beterrabad/socket2.ha | 61 +++++++++++++++++++++++++++++++++++++++++


diff --git a/cmd/beterrabad/main.ha b/cmd/beterrabad/main.ha
index e033f83aaf80be10a2daef8c5e2b12e4dd411257..852c5ca1a4458a4a24fb57df69d229c9fa7004ef 100644
--- a/cmd/beterrabad/main.ha
+++ b/cmd/beterrabad/main.ha
@@ -23,7 +23,7 @@
 	//const flags = rt::fcntl(sock.sock, rt::F_GETFL, 0)!;
 	//rt::fcntl(sock.sock, rt::F_SETFL, flags | rt::O_CLOEXEC)!;
 
-	//log::println("beterrabad running");
-	//for (dispatch2(&serv)) void;
-	//log::println("beterrabad terminated");
+	log::println("beterrabad running");
+	for (dispatch2(&serv)) void;
+	log::println("beterrabad terminated");
 };




diff --git a/cmd/beterrabad/socket2.ha b/cmd/beterrabad/socket2.ha
index e6917fc99752acc4cb310cebbe7095ffa75b68bd..8b78ab54969d44a52aae5cecf2fb31005f8fba2b 100644
--- a/cmd/beterrabad/socket2.ha
+++ b/cmd/beterrabad/socket2.ha
@@ -1,18 +1,28 @@
 use io;
 use dirs;
 use fs;
+use errors;
 use log;
 use net::unix;
 use net;
 use os;
 use unix::poll;
+use unix::signal;
 use unix::poll::{event};
 use path;
 
 type server2 = struct {
 	sock: net::socket,
+	signalfd: io::file,
 	pollfd: []poll::pollfd,
+	clients: []client2,
 	disconnected: bool
+};
+
+type client2 = struct {
+	server: *server2,
+	sock: io::file,
+	pollfd: *poll::pollfd
 };
 
 fn bind2(fd: io::file) server2 = {
@@ -48,12 +58,63 @@
 	return server2 {
 		sock = sock,
 		pollfd = pollfd,
+		signalfd = fd,
 		...
 	};
 };
 
+fn dispatch2(s: *server2) bool = {
+	match(poll::poll(s.pollfd, poll::INDEF)) {
+	case uint => {
+		if (s.pollfd[0].revents & event::POLLIN != 0) {
+			log::printfln("accpet");
+			accept2(s);
+		};
+
+		if (s.pollfd[1].revents & event::POLLIN != 0) {
+			signal::read(s.signalfd)!;
+			return false;
+		};
+	};
+	case let err: errors::error =>
+		log::fatal("poll:", errors::strerror(err));
+	};
+
+	return true;
+};
+
+// TODO: Check if we reached max client connections first
+fn accept2(s: *server2) void = {
+	let clientsock = match(net::accept(s.sock)) {
+	case let sock: net::socket =>
+		yield sock;
+	case let err: net::error =>
+		log::fatalf("Couldn't grab a client sock due to {}", net::strerror(err));
+	};
+
+	append(s.pollfd, poll::pollfd {
+		fd = clientsock,
+		events = event::POLLIN | event::POLLHUP,
+		...
+	});
+
+	let pollfd = &s.pollfd[len(s.pollfd) - 1];
+
+	append(s.clients, client2 {
+		server = s,
+		sock = clientsock,
+		pollfd = pollfd,
+		...
+	});
+};
+
 // TODO: Walk over every connected client and disconnect them & free the clients
 fn shutdown2(s: *server2) void = {
+	for (let i = 0z; i < len(s.clients); i += 1) {
+		net::close(s.clients[i].sock)!;
+	};
+
+	free(s.clients);
 	free(s.pollfd);
 
 	let pathbuf = path::init();