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();