Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>
all: use correct socket implementation
cmd/beterrabad/client.ha | 77 ----------------------------------------- cmd/beterrabad/main.ha | 6 +- cmd/beterrabad/socket2.ha | 62 ++++++++++++++++----------------
diff --git a/cmd/beterrabad/client.ha b/cmd/beterrabad/client.ha deleted file mode 100644 index 3303ebf7aba954419d688ef00013a8085973a883..0000000000000000000000000000000000000000 --- a/cmd/beterrabad/client.ha +++ /dev/null @@ -1,77 +0,0 @@ -use fmt; -use io; -use strings; -use unix::poll; -use unix::poll::{event}; - -type state = enum { - READ, - WRITE, - WRITE_ERROR, -}; - -type client = struct { - server: *server, - sock: io::file, - state: state, - pollfd: *poll::pollfd, - rbuf: []u8, - wbuf: []u8, -}; - -// Immediately disconnects a client, without sending them an error message. -fn disconnect(c: *client) void = { - io::close(c.sock)!; - free(c.rbuf); - free(c.wbuf); - - let serv = c.server; - let i = (c: uintptr - serv.clients: *[*]client: uintptr): size / size(client); - delete(serv.clients[i]); - delete(serv.pollfd[i + POLLFD_RESERVED]); - for (i < len(serv.clients); i += 1) { - serv.clients[i].pollfd = &serv.pollfd[i + POLLFD_RESERVED]; - }; - - serv.disconnected = true; -}; - -// Prepares an error message to send to a client. They will be disconnected once -// the error message is sent. -fn disconnect_error( - client: *client, - fmt: str, - args: fmt::field... -) void = { - free(client.wbuf); - const msg = fmt::asprintf(fmt, args...); - client.wbuf = strings::toutf8(msg); - client.state = state::WRITE_ERROR; - client.pollfd.events = event::POLLOUT | event::POLLHUP; -}; - -// Writes data to the client. Takes ownership over the buffer. -fn write(client: *client, buf: []u8) void = { - assert(client.state != state::WRITE - && client.state != state::WRITE_ERROR); - client.wbuf = buf; - client.state = state::WRITE; - client.pollfd.events = event::POLLOUT | event::POLLHUP; -}; - -// Writes data to the client. Duplicates the buffer. -fn writebuf(client: *client, buf: []u8) void = { - write(client, alloc(buf...)); -}; - -// Writes a formatted string to the client. -fn writefmt( - client: *client, - fmt: str, - args: fmt::field... -) void = { - let buf = fmt::asprintf(fmt, args...); - let buf = strings::toutf8(buf); - append(buf, '\n'); - write(client, buf); -}; diff --git a/cmd/beterrabad/main.ha b/cmd/beterrabad/main.ha index 852c5ca1a4458a4a24fb57df69d229c9fa7004ef..dc8c90d65a1e83710adad744661e23a2fd64ad62 100644 --- a/cmd/beterrabad/main.ha +++ b/cmd/beterrabad/main.ha @@ -16,14 +16,14 @@ signal::block(signal::SIGINT, signal::SIGTERM); const sigfd = signal::signalfd(signal::SIGINT, signal::SIGTERM)!; defer io::close(sigfd)!; - const serv = bind2(sigfd); + const serv = bind(sigfd); - defer shutdown2(&serv); + defer shutdown(&serv); //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; + for (dispatch(&serv)) void; log::println("beterrabad terminated"); }; diff --git a/cmd/beterrabad/socket2.ha b/cmd/beterrabad/socket2.ha index c5796abebf1509c4396e2b3fd552a54d5b39736f..bb5ee0999d36468a1e583781dd7b934b559b6ec7 100644 --- a/cmd/beterrabad/socket2.ha +++ b/cmd/beterrabad/socket2.ha @@ -15,32 +15,32 @@ use bufio; use strings; use encoding::utf8; -type servererror2 = !(io::error | fs::error); +type servererror = !(io::error | fs::error); -type server2 = struct { +type server = struct { sock: net::socket, signalfd: io::file, pollfd: []poll::pollfd, - clients: []client2, + clients: []client, disconnected: bool }; -type client2 = struct { - server: *server2, +type client = struct { + server: *server, sock: io::file, pollfd: *poll::pollfd, - state: state2, + state: state, wbuf: []u8, rbuf: []u8 }; -type state2 = enum { +type state = enum { READ, WRITE, WRITE_ERROR, }; -fn bind2(fd: io::file) server2 = { +fn bind(fd: io::file) server = { let runtime = match(dirs::runtime()) { case let dir: str => yield dir; @@ -70,7 +70,7 @@ events = event::POLLIN, ... }]); - return server2 { + return server { sock = sock, pollfd = pollfd, signalfd = fd, @@ -78,12 +78,12 @@ ... }; }; -fn dispatch2(s: *server2) bool = { +fn dispatch(s: *server) bool = { match(poll::poll(s.pollfd, poll::INDEF)) { case uint => { if (s.pollfd[0].revents & event::POLLIN != 0) { log::printfln("accpet"); - accept2(s); + accept(s); }; if (s.pollfd[1].revents & event::POLLIN != 0) { @@ -92,7 +92,7 @@ return false; }; for (let i = 2z; i < len(s.pollfd); i += 1) { - dispatch_client2(s, &s.clients[i - 2]); + dispatch_client(s, &s.clients[i - 2]); if (s.disconnected) { // Restart loop on client disconnect @@ -108,7 +108,7 @@ return true; }; -fn dispatch_client2(s: *server2, client: *client2) void = { +fn dispatch_client(s: *server, client: *client) void = { let cpollfd = client.pollfd; if (cpollfd.revents & event::POLLERR != 0) { @@ -130,7 +130,7 @@ write_client(s, client); }; }; -fn write_client(s: *server2, client: *client2) void = { +fn write_client(s: *server, client: *client) void = { let sz = match (io::write(client.sock, client.wbuf)) { case let z: size => yield z; @@ -147,16 +147,16 @@ // Clean up the buffer delete(client.wbuf[..sz]); switch (client.state) { - case state2::WRITE => - client.state = state2::READ; + case state::WRITE => + client.state = state::READ; client.pollfd.events = event::POLLIN | event::POLLHUP; - case state2::WRITE_ERROR => + case state::WRITE_ERROR => disconnect_client(client); case => abort(); }; }; -fn read_client(s: *server2, client: *client2) void = { +fn read_client(s: *server, client: *client) void = { let bufline = match (bufio::scanline(client.sock)) { case let l: []u8 => yield l; @@ -173,15 +173,15 @@ case utf8::invalid => log::fatal("invalid utf-8"); }; - match (exec2(line, client)) { + match (exec(line, client)) { case void => void; - case servererror2 => + case servererror => log::fatal("Fudeu"); }; }; -fn exec2(command: str, client: *client2) (servererror2 | void) = { +fn exec(command: str, client: *client) (servererror | void) = { let buf = bufio::dynamic(io::mode::WRITE); // TODO: Flesh out command execution here @@ -190,25 +190,25 @@ fmt::fprintf(&buf, "pong\n")?; }; fmt::fprintln(&buf, "end")?; - writebuf2(client, bufio::buffer(&buf)); + writebuf(client, bufio::buffer(&buf)); }; // Writes data to the client. Takes ownership over the buffer. -fn commit_write(client: *client2, buf: []u8) void = { - assert(client.state != state2::WRITE - && client.state != state2::WRITE_ERROR); +fn commit_write(client: *client, buf: []u8) void = { + assert(client.state != state::WRITE + && client.state != state::WRITE_ERROR); client.wbuf = buf; - client.state = state2::WRITE; + client.state = state::WRITE; client.pollfd.events = event::POLLOUT | event::POLLHUP; }; // Writes data to the client. Duplicates the buffer. -fn writebuf2(client: *client2, buf: []u8) void = { +fn writebuf(client: *client, buf: []u8) void = { commit_write(client, alloc(buf...)); }; // TODO: Check if we reached max client connections first -fn accept2(s: *server2) void = { +fn accept(s: *server) void = { let clientsock = match(net::accept(s.sock)) { case let sock: net::socket => yield sock; @@ -224,7 +224,7 @@ }); let pollfd = &s.pollfd[len(s.pollfd) - 1]; - append(s.clients, client2 { + append(s.clients, client { server = s, sock = clientsock, pollfd = pollfd, @@ -233,7 +233,7 @@ }); }; // Immediately disconnects a client, without sending them an error message. -fn disconnect_client(c: *client2) void = { +fn disconnect_client(c: *client) void = { io::close(c.sock)!; free(c.rbuf); free(c.wbuf); @@ -250,7 +250,7 @@ serv.disconnected = true; }; // TODO: Walk over every connected client and disconnect them & free the clients -fn shutdown2(s: *server2) void = { +fn shutdown(s: *server) void = { for (let i = 0z; i < len(s.clients); i += 1) { net::close(s.clients[i].sock)!; free(s.clients[i].wbuf);