hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 111a367e000d269fe12fabf095a71099ae84c620
parent c445e60fc732450da4c6b530fcecad1511b2c3b2
Author: Sebastian <sebastian@sebsite.pw>
Date:   Sun,  5 Jun 2022 00:19:38 -0400

net: add socket type

Implements: https://todo.sr.ht/~sircmpwn/hare/537
Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mnet/+freebsd.ha | 15+++++++++------
Mnet/+linux.ha | 15+++++++++------
Mnet/dial/dial.ha | 5++---
Mnet/dial/ip.ha | 11++++-------
Mnet/dial/registry.ha | 4+---
Mnet/dns/query.ha | 6+++---
Mnet/tcp/+freebsd.ha | 6+++---
Mnet/tcp/+linux.ha | 6+++---
Mnet/tcp/listener.ha | 7+++++--
Mnet/udp/+freebsd.ha | 10+++++-----
Mnet/udp/+linux.ha | 10+++++-----
Mnet/unix/+freebsd.ha | 4++--
Mnet/unix/+linux.ha | 4++--
Mnet/unix/dial.ha | 5++---
Mnet/unix/listener.ha | 8+++++---
Mscripts/gen-stdlib | 2+-
Mstdlib.mk | 4++--
17 files changed, 63 insertions(+), 59 deletions(-)

diff --git a/net/+freebsd.ha b/net/+freebsd.ha @@ -10,7 +10,10 @@ use os; use rt; use strings; -// Optional flags to [[accept]] to be set on the returned [[io::file]]. +// A network socket. +export type socket = io::file; + +// Optional flags to [[accept]] to be set on the returned [[socket]]. // See the O_CLOEXEC and O_NONBLOCK sections of open(2) for details. // Note that CLOEXEC is on by default, and NOCLOEXEC flag disables it. export type sockflags = enum int { @@ -21,7 +24,7 @@ export type sockflags = enum int { // Accepts the next connection from a socket. Blocks until a new connection is // available. Optionally accepts NOCLOEXEC and NONBLOCK flags. If flags are // supplied, the [[io::file]] returned will have the supplied flags set. -export fn accept(sock: io::file, flags: sockflags...) (io::file | error) = { +export fn accept(sock: socket, flags: sockflags...) (socket | error) = { let sn = rt::sockaddr {...}; const sz = size(rt::sockaddr): u32; // Apply any supplied flags @@ -40,8 +43,8 @@ export fn accept(sock: io::file, flags: sockflags...) (io::file | error) = { }; // Shuts down a listening socket. -export fn shutdown(sock: io::file) void = { - rt::close(sock)!; +export fn shutdown(sock: socket) void = { + io::close(sock)!; }; fn msg_to_native(msg: *msghdr) *rt::msghdr = { @@ -58,7 +61,7 @@ fn msg_to_native(msg: *msghdr) *rt::msghdr = { }; // Sends a message to a socket. See [[newmsg]] for details. -export fn sendmsg(sock: io::file, msg: *msghdr) (size | error) = { +export fn sendmsg(sock: socket, msg: *msghdr) (size | error) = { // TODO: Flags match (rt::sendmsg(sock, msg_to_native(msg), 0)) { case let n: int => @@ -69,7 +72,7 @@ export fn sendmsg(sock: io::file, msg: *msghdr) (size | error) = { }; // Receives a message from a socket. See [[newmsg]] for details. -export fn recvmsg(sock: io::file, msg: *msghdr) (size | error) = { +export fn recvmsg(sock: socket, msg: *msghdr) (size | error) = { // TODO: Flags match (rt::recvmsg(sock, msg_to_native(msg), 0)) { case let n: int => diff --git a/net/+linux.ha b/net/+linux.ha @@ -10,7 +10,10 @@ use os; use rt; use strings; -// Optional flags to [[accept]] to be set on the returned [[io::file]]. +// A network socket. +export type socket = io::file; + +// Optional flags to [[accept]] to be set on the returned [[socket]]. // See the O_CLOEXEC and O_NONBLOCK sections of open(2) for details. // Note that CLOEXEC is on by default, and NOCLOEXEC flag disables it. export type sockflags = enum int { @@ -21,7 +24,7 @@ export type sockflags = enum int { // Accepts the next connection from a socket. Blocks until a new connection is // available. Optionally accepts NOCLOEXEC and NONBLOCK flags. If flags are // supplied, the [[io::file]] returned will have the supplied flags set. -export fn accept(sock: io::file, flags: sockflags...) (io::file | error) = { +export fn accept(sock: socket, flags: sockflags...) (socket | error) = { let sn = rt::sockaddr {...}; const sz = size(rt::sockaddr): u32; // Apply any supplied flags @@ -40,8 +43,8 @@ export fn accept(sock: io::file, flags: sockflags...) (io::file | error) = { }; // Shuts down a listening socket. -export fn shutdown(sock: io::file) void = { - rt::close(sock)!; +export fn shutdown(sock: socket) void = { + io::close(sock)!; }; fn msg_to_native(msg: *msghdr) *rt::msghdr = { @@ -58,7 +61,7 @@ fn msg_to_native(msg: *msghdr) *rt::msghdr = { }; // Sends a message to a socket. See [[newmsg]] for details. -export fn sendmsg(sock: io::file, msg: *msghdr) (size | error) = { +export fn sendmsg(sock: socket, msg: *msghdr) (size | error) = { // TODO: Flags match (rt::sendmsg(sock, msg_to_native(msg), 0)) { case let n: int => @@ -69,7 +72,7 @@ export fn sendmsg(sock: io::file, msg: *msghdr) (size | error) = { }; // Receives a message from a socket. See [[newmsg]] for details. -export fn recvmsg(sock: io::file, msg: *msghdr) (size | error) = { +export fn recvmsg(sock: socket, msg: *msghdr) (size | error) = { // TODO: Flags match (rt::recvmsg(sock, msg_to_native(msg), 0)) { case let n: int => diff --git a/net/dial/dial.ha b/net/dial/dial.ha @@ -1,10 +1,9 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> -use io; use net; // Dials a remote address, establishing a connection and returning the resulting -// [[io::file]]. The proto parameter should be the transport protocol (e.g. +// [[net::socket]]. The proto parameter should be the transport protocol (e.g. // "tcp"), the address parameter should be the remote address, and the service // should be the name of the service, or the default port to use. // @@ -35,7 +34,7 @@ export fn dial( proto: str, address: str, service: str, -) (io::file | error) = { +) (net::socket | error) = { for (let i = 0z; i < len(default_protocols); i += 1) { const p = default_protocols[i]; if (p.name == proto) { diff --git a/net/dial/ip.ha b/net/dial/ip.ha @@ -4,20 +4,17 @@ // (c) 2021 Eyal Sawady <ecs@d2evs.net> // Provides default dialers for tcp and udp -use io; use net; -use net::ip; use net::tcp; use net::udp; -use io; -fn dial_tcp(addr: str, service: str) (io::file | error) = { +fn dial_tcp(addr: str, service: str) (net::socket | error) = { const result = resolve("tcp", addr, service)?; const addrs = result.0, port = result.1; for (let i = 0z; i < len(addrs); i += 1) { const addr = addrs[i]; match (tcp::connect(addr, port)) { - case let conn: io::file => + case let conn: net::socket => return conn; case let err: net::error => if (i + 1 >= len(addrs)) { @@ -28,13 +25,13 @@ fn dial_tcp(addr: str, service: str) (io::file | error) = { abort(); // Unreachable }; -fn dial_udp(addr: str, service: str) (io::file | error) = { +fn dial_udp(addr: str, service: str) (net::socket | error) = { const result = resolve("udp", addr, service)?; const addrs = result.0, port = result.1; for (let i = 0z; i < len(addrs); i += 1) { const addr = addrs[i]; match (udp::connect(addr, port)) { - case let sock: io::file => + case let sock: net::socket => return sock; case let err: net::error => if (i + 1 >= len(addrs)) { diff --git a/net/dial/registry.ha b/net/dial/registry.ha @@ -1,8 +1,6 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> // (c) 2021 Eyal Sawady <ecs@d2evs.net> -use errors; -use io; use net; use net::dns; @@ -33,7 +31,7 @@ export fn strerror(err: error) const str = { }; // A dialer is a function which implements dial for a specific protocol. -export type dialer = fn(addr: str, service: str) (io::file | error); +export type dialer = fn(addr: str, service: str) (net::socket | error); type protocol = struct { name: str, diff --git a/net/dns/query.ha b/net/dns/query.ha @@ -1,7 +1,7 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> use errors; -use io; +use net; use net::ip; use net::udp; use time; @@ -26,9 +26,9 @@ export fn query(query: *message, servers: ip::addr...) (*message | error) = { }; let socket4 = udp::listen(ip::ANY_V4, 0)?; - defer io::close(socket4)!; + defer net::close(socket4)!; let socket6 = udp::listen(ip::ANY_V6, 0)?; - defer io::close(socket6)!; + defer net::close(socket6)!; const pollfd: [_]poll::pollfd = [ poll::pollfd { fd = socket4, diff --git a/net/tcp/+freebsd.ha b/net/tcp/+freebsd.ha @@ -14,7 +14,7 @@ export fn connect( addr: ip::addr, port: u16, options: connect_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { const sockaddr = ip::to_native(addr, port); const family = match (addr) { case ip::addr4 => @@ -59,7 +59,7 @@ export fn listen( addr: ip::addr, port: u16, options: listen_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { const sockaddr = ip::to_native(addr, port); const family = match (addr) { case ip::addr4 => @@ -133,7 +133,7 @@ export fn listen( // Returns the remote address for a given connection, or void if none is // available. -export fn peeraddr(peer: io::file) ((ip::addr, u16) | void) = { +export fn peeraddr(peer: net::socket) ((ip::addr, u16) | void) = { let sn = rt::sockaddr {...}; let sz = size(rt::sockaddr): u32; if (rt::getpeername(peer, &sn, &sz) is rt::errno) { diff --git a/net/tcp/+linux.ha b/net/tcp/+linux.ha @@ -14,7 +14,7 @@ export fn connect( addr: ip::addr, port: u16, options: connect_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { const sockaddr = ip::to_native(addr, port); const family = match (addr) { case ip::addr4 => @@ -59,7 +59,7 @@ export fn listen( addr: ip::addr, port: u16, options: listen_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { const sockaddr = ip::to_native(addr, port); const family = match (addr) { case ip::addr4 => @@ -132,7 +132,7 @@ export fn listen( // Returns the remote address for a given connection, or void if none is // available. -export fn peeraddr(peer: io::file) ((ip::addr, u16) | void) = { +export fn peeraddr(peer: net::socket) ((ip::addr, u16) | void) = { let sn = rt::sockaddr {...}; let sz = size(rt::sockaddr): u32; if (rt::getpeername(peer, &sn, &sz) is rt::errno) { diff --git a/net/tcp/listener.ha b/net/tcp/listener.ha @@ -5,8 +5,11 @@ use net; // Accepts the next connection from a socket. Blocks until a new connection is // available. This is a convenience wrapper around [[net::accept]]. -export fn accept(sock: io::file, flags: net::sockflags...) (io::file | net::error) = net::accept(sock, flags...); +export fn accept( + sock: net::socket, + flags: net::sockflags... +) (net::socket | net::error) = net::accept(sock, flags...); // Shuts down a listening socket. This is a convenience wrapper around // [[net::shutdown]]. -export fn shutdown(sock: io::file) void = net::shutdown(sock); +export fn shutdown(sock: net::socket) void = net::shutdown(sock); diff --git a/net/udp/+freebsd.ha b/net/udp/+freebsd.ha @@ -13,7 +13,7 @@ export fn connect( dest: ip::addr, port: u16, options: connect_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { const family = match (dest) { case ip::addr4 => yield rt::AF_INET: int; @@ -48,7 +48,7 @@ export fn listen( addr: ip::addr, port: u16, options: listen_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { const family = match (addr) { case ip::addr4 => yield rt::AF_INET: int; @@ -101,7 +101,7 @@ export fn listen( }; // Sends a UDP packet to the destination previously specified by [[connect]]. -export fn send(sock: io::file, buf: []u8) (size | net::error) = { +export fn send(sock: net::socket, buf: []u8) (size | net::error) = { match (rt::send(sock, buf: *[*]u8, len(buf), 0)) { case let sz: size => return sz; @@ -112,7 +112,7 @@ export fn send(sock: io::file, buf: []u8) (size | net::error) = { // Sends a UDP packet using this socket. export fn sendto( - sock: io::file, + sock: net::socket, buf: []u8, dest: ip::addr, port: u16, @@ -129,7 +129,7 @@ export fn sendto( // Receives a UDP packet from a bound socket. export fn recvfrom( - sock: io::file, + sock: net::socket, buf: []u8, src: nullable *ip::addr, port: nullable *u16, diff --git a/net/udp/+linux.ha b/net/udp/+linux.ha @@ -13,7 +13,7 @@ export fn connect( dest: ip::addr, port: u16, options: connect_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { const family = match (dest) { case ip::addr4 => yield rt::AF_INET: int; @@ -48,7 +48,7 @@ export fn listen( addr: ip::addr, port: u16, options: listen_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { const family = match (addr) { case ip::addr4 => yield rt::AF_INET: int; @@ -101,7 +101,7 @@ export fn listen( }; // Sends a UDP packet to the destination previously specified by [[connect]]. -export fn send(sock: io::file, buf: []u8) (size | net::error) = { +export fn send(sock: net::socket, buf: []u8) (size | net::error) = { match (rt::send(sock, buf: *[*]u8, len(buf), 0)) { case let sz: size => return sz; @@ -112,7 +112,7 @@ export fn send(sock: io::file, buf: []u8) (size | net::error) = { // Sends a UDP packet using this socket. export fn sendto( - sock: io::file, + sock: net::socket, buf: []u8, dest: ip::addr, port: u16, @@ -129,7 +129,7 @@ export fn sendto( // Receives a UDP packet from a bound socket. export fn recvfrom( - sock: io::file, + sock: net::socket, buf: []u8, src: nullable *ip::addr, port: nullable *u16, diff --git a/net/unix/+freebsd.ha b/net/unix/+freebsd.ha @@ -15,7 +15,7 @@ use types; export fn connect( addr: addr, options: connect_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { let sockaddr = match (to_native(addr)) { case let a: rt::sockaddr => yield a; @@ -49,7 +49,7 @@ export fn connect( export fn listen( addr: addr, options: listen_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { let sockaddr = match (to_native(addr)) { case let a: rt::sockaddr => yield a; diff --git a/net/unix/+linux.ha b/net/unix/+linux.ha @@ -16,7 +16,7 @@ use types; export fn connect( addr: addr, options: connect_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { let sockaddr = match (to_native(addr)) { case let a: rt::sockaddr => yield a; @@ -50,7 +50,7 @@ export fn connect( export fn listen( addr: addr, options: listen_option... -) (io::file | net::error) = { +) (net::socket | net::error) = { let sockaddr = match (to_native(addr)) { case let a: rt::sockaddr => yield a; diff --git a/net/unix/dial.ha b/net/unix/dial.ha @@ -1,13 +1,12 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> // (c) 2021 Eyal Sawady <ecs@d2evs.net> -use io; use net::dial; use net; -fn dial_unix(addr: str, service: str) (io::file | dial::error) = { +fn dial_unix(addr: str, service: str) (net::socket | dial::error) = { match (connect(addr)) { - case let conn: io::file => + case let conn: net::socket => return conn; case let err: net::error => return err; diff --git a/net/unix/listener.ha b/net/unix/listener.ha @@ -1,12 +1,14 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> -use io; use net; // Accepts the next connection from a socket. Blocks until a new connection is // available. This is a convenience wrapper around [[net::accept]]. -export fn accept(sock: io::file, flags: net::sockflags...) (io::file | net::error) = net::accept(sock, flags...); +export fn accept( + sock: net::socket, + flags: net::sockflags... +) (net::socket | net::error) = net::accept(sock, flags...); // Shuts down a listening socket. This is a convenience wrapper around // [[net::shutdown]]. -export fn shutdown(sock: io::file) void = net::shutdown(sock); +export fn shutdown(sock: net::socket) void = net::shutdown(sock); diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -957,7 +957,7 @@ net_dial() { dial.ha \ ip.ha \ resolve.ha - gen_ssa net::dial io net net::ip net::tcp net::udp net::dns \ + gen_ssa net::dial net net::ip net::tcp net::udp net::dns \ crypto::random strconv strings unix::hosts } diff --git a/stdlib.mk b/stdlib.mk @@ -1563,7 +1563,7 @@ stdlib_net_dial_any_srcs = \ $(STDLIB)/net/dial/ip.ha \ $(STDLIB)/net/dial/resolve.ha -$(HARECACHE)/net/dial/net_dial-any.ssa: $(stdlib_net_dial_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_net_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_net_tcp_$(PLATFORM)) $(stdlib_net_udp_$(PLATFORM)) $(stdlib_net_dns_$(PLATFORM)) $(stdlib_crypto_random_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_unix_hosts_$(PLATFORM)) +$(HARECACHE)/net/dial/net_dial-any.ssa: $(stdlib_net_dial_any_srcs) $(stdlib_rt) $(stdlib_net_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_net_tcp_$(PLATFORM)) $(stdlib_net_udp_$(PLATFORM)) $(stdlib_net_dns_$(PLATFORM)) $(stdlib_crypto_random_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_unix_hosts_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/net/dial @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::dial \ @@ -3724,7 +3724,7 @@ testlib_net_dial_any_srcs = \ $(STDLIB)/net/dial/ip.ha \ $(STDLIB)/net/dial/resolve.ha -$(TESTCACHE)/net/dial/net_dial-any.ssa: $(testlib_net_dial_any_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_net_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_net_tcp_$(PLATFORM)) $(testlib_net_udp_$(PLATFORM)) $(testlib_net_dns_$(PLATFORM)) $(testlib_crypto_random_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_unix_hosts_$(PLATFORM)) +$(TESTCACHE)/net/dial/net_dial-any.ssa: $(testlib_net_dial_any_srcs) $(testlib_rt) $(testlib_net_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_net_tcp_$(PLATFORM)) $(testlib_net_udp_$(PLATFORM)) $(testlib_net_dns_$(PLATFORM)) $(testlib_crypto_random_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_unix_hosts_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/net/dial @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::dial \