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:
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 \