Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>
server: reimplement from scratch socket handling => bind and shutdown
cmd/beterrabad/main.ha | 14 +++--- cmd/beterrabad/socket2.ha | 72 +++++++++++++++++++++++++++++++++++++++++
diff --git a/cmd/beterrabad/main.ha b/cmd/beterrabad/main.ha index 1be097f72b9da20f075df57c70051a1165159ee0..e033f83aaf80be10a2daef8c5e2b12e4dd411257 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 sock = bind(sigfd); + const serv = bind2(sigfd); - defer shutdown(&sock); + defer shutdown2(&serv); - const flags = rt::fcntl(sock.sock, rt::F_GETFL, 0)!; - rt::fcntl(sock.sock, rt::F_SETFL, flags | rt::O_CLOEXEC)!; + //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 (dispatch(&sock)) 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 new file mode 100644 index 0000000000000000000000000000000000000000..e6917fc99752acc4cb310cebbe7095ffa75b68bd --- /dev/null +++ b/cmd/beterrabad/socket2.ha @@ -0,0 +1,72 @@ +use io; +use dirs; +use fs; +use log; +use net::unix; +use net; +use os; +use unix::poll; +use unix::poll::{event}; +use path; + +type server2 = struct { + sock: net::socket, + pollfd: []poll::pollfd, + disconnected: bool +}; + +fn bind2(fd: io::file) server2 = { + let runtime = match(dirs::runtime()) { + case let dir: str => + yield dir; + case let err: fs::error => + log::fatalf("Some error on trying to find runtime dir {}", + fs::strerror(err)); + }; + + let pathbuf = path::init(); + path::add(&pathbuf, runtime, "beterrabad")!; + let sockpath = path::string(&pathbuf); + + const sock = match(unix::listen(sockpath, net::sockflags::NOCLOEXEC)) { + case let err: net::error => + log::fatalf("Could not create socket", net::strerror(err)); + case let unixsock: net::socket => + yield unixsock; + }; + + let pollfd = alloc([poll::pollfd { + fd = sock, + events = event::POLLIN, + ... + }, poll::pollfd { + fd = fd, + events = event::POLLIN, + ... + }]); + + return server2 { + sock = sock, + pollfd = pollfd, + ... + }; +}; + +// TODO: Walk over every connected client and disconnect them & free the clients +fn shutdown2(s: *server2) void = { + free(s.pollfd); + + let pathbuf = path::init(); + path::add(&pathbuf, dirs::runtime()!, "beterrabad")!; + + os::remove(path::string(&pathbuf))!; + + match(net::close(s.sock)) { + case let err: net::error => + log::printfln( + "There was some error trying to close the socket, {}", + net::strerror(err) + ); + case void => void; + }; +};