hare

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

commit c2c41c1d2616baedbc419d53e75dcf29c4dae178
parent cf845d56add43364b4f9f0e74be094da6cbe3930
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 13 Apr 2022 13:38:17 +0200

net: convert listener to io::file

Implements: https://todo.sr.ht/~sircmpwn/hare/605
Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mnet/+freebsd.ha | 30+++++++-----------------------
Mnet/+linux.ha | 30+++++++-----------------------
Dnet/listener.ha | 37-------------------------------------
Mnet/tcp/+freebsd.ha | 12+++---------
Mnet/tcp/+linux.ha | 12+++---------
Mnet/tcp/listener.ha | 14+++++---------
Mnet/unix/+freebsd.ha | 12+++---------
Mnet/unix/+linux.ha | 12+++---------
Mnet/unix/listener.ha | 14+++++---------
Mscripts/gen-stdlib | 2--
Mstdlib.mk | 4----
11 files changed, 36 insertions(+), 143 deletions(-)

diff --git a/net/+freebsd.ha b/net/+freebsd.ha @@ -1,8 +1,6 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> // (c) 2021 Eyal Sawady <ecs@d2evs.net> - -// Some common code for handling sockets on +freebsd use errors; use fmt; use io; @@ -11,24 +9,12 @@ use os; use rt; use strings; -export type stream_listener = struct { - l: listener, - fd: int, -}; - -// Gets the fd of the listener's socket. This function is not portable. -export fn listenerfd(l: *listener) (io::file | void) = { - if (l.accept == &stream_accept) { - return (l: *stream_listener).fd; - }; -}; - -export fn stream_accept(l: *listener) (io::file | error) = { - assert(l.accept == &stream_accept); - let l = l: *stream_listener; +// Accepts the next connection from a socket. Blocks until a new connection is +// available. +export fn accept(sock: io::file) (io::file | error) = { let sn = rt::sockaddr {...}; const sz = size(rt::sockaddr): u32; - const fd = match (rt::accept(l.fd, &sn, &sz)) { + const fd = match (rt::accept(sock, &sn, &sz)) { case let err: rt::errno => return errors::errno(err); case let fd: int => @@ -37,11 +23,9 @@ export fn stream_accept(l: *listener) (io::file | error) = { return io::fdopen(fd); }; -export fn stream_shutdown(l: *listener) void = { - assert(l.shutdown == &stream_shutdown); - let l = l: *stream_listener; - rt::close(l.fd)!; - free(l); +// Shuts down a listening socket. +export fn shutdown(sock: io::file) void = { + rt::close(sock)!; }; fn msg_to_native(msg: *msghdr) *rt::msghdr = { diff --git a/net/+linux.ha b/net/+linux.ha @@ -1,8 +1,6 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> // (c) 2021 Eyal Sawady <ecs@d2evs.net> - -// Some common code for handling sockets on +linux use errors; use fmt; use io; @@ -11,24 +9,12 @@ use os; use rt; use strings; -export type stream_listener = struct { - l: listener, - fd: int, -}; - -// Gets the file of a listener's socket. -export fn listenerfd(l: *listener) (io::file | void) = { - if (l.accept == &stream_accept) { - return (l: *stream_listener).fd; - }; -}; - -export fn stream_accept(l: *listener) (io::file | error) = { - assert(l.accept == &stream_accept); - let l = l: *stream_listener; +// Accepts the next connection from a socket. Blocks until a new connection is +// available. +export fn accept(sock: io::file) (io::file | error) = { let sn = rt::sockaddr {...}; const sz = size(rt::sockaddr): u32; - const fd = match (rt::accept(l.fd, &sn, &sz)) { + const fd = match (rt::accept(sock, &sn, &sz)) { case let err: rt::errno => return errors::errno(err); case let fd: int => @@ -37,11 +23,9 @@ export fn stream_accept(l: *listener) (io::file | error) = { return io::fdopen(fd); }; -export fn stream_shutdown(l: *listener) void = { - assert(l.shutdown == &stream_shutdown); - let l = l: *stream_listener; - rt::close(l.fd)!; - free(l); +// Shuts down a listening socket. +export fn shutdown(sock: io::file) void = { + rt::close(sock)!; }; fn msg_to_native(msg: *msghdr) *rt::msghdr = { diff --git a/net/listener.ha b/net/listener.ha @@ -1,37 +0,0 @@ -// License: MPL-2.0 -// (c) 2021 Drew DeVault <sir@cmpwn.com> -// (c) 2021-2022 Eyal Sawady <ecs@d2evs.net> -use errors; -use io; - -// A listener binds a socket and listens for incoming traffic for some -// unspecified protocol. This is generally most useful for providing an -// abstraction between a TCP socket and Unix socket (or any other stream -// oriented protocol), where the implementation which accepts and processes -// connections is not aware of the underlying transport. Most users will not -// need to use this interface directly, preferring functions such as -// [[net::tcp::accept]]. -export type listener = struct { - accept: nullable *fn(l: *listener) (io::file | error), - shutdown: nullable *fn(l: *listener) void, -}; - -// Accepts the next connection from a listener. Blocks until a new connection is -// available. -export fn accept(l: *listener) (io::file | error) = { - match (l.accept) { - case let f: *fn(l: *listener) (io::file | error) => - return f(l); - case null => - return errors::unsupported; - }; -}; - -// Shuts down a [[listener]] and frees resources associated with it. -export fn shutdown(l: *listener) void = { - match (l.shutdown) { - case let f: *fn(l: *listener) void => - f(l); - case null => void; - }; -}; diff --git a/net/tcp/+freebsd.ha b/net/tcp/+freebsd.ha @@ -44,12 +44,12 @@ export fn connect( return io::fdopen(sockfd); }; -// Binds a TCP listener to the given address. +// Binds a TCP socket to the given address. export fn listen( addr: ip::addr, port: u16, options: listen_option... -) (*net::listener | net::error) = { +) (io::file | net::error) = { const sockaddr = ip::to_native(addr, port); const family = match (addr) { case ip::addr4 => @@ -111,13 +111,7 @@ export fn listen( *portout = addr.1; }; - return alloc(net::stream_listener { - l = net::listener { - accept = &net::stream_accept, - shutdown = &net::stream_shutdown, - }, - fd = sockfd, - }): *net::listener; + return sockfd; }; // Returns the remote address for a given connection, or void if none is diff --git a/net/tcp/+linux.ha b/net/tcp/+linux.ha @@ -44,12 +44,12 @@ export fn connect( return io::fdopen(sockfd); }; -// Binds a TCP listener to the given address. +// Binds a TCP socket to the given address. export fn listen( addr: ip::addr, port: u16, options: listen_option... -) (*net::listener | net::error) = { +) (io::file | net::error) = { const sockaddr = ip::to_native(addr, port); const family = match (addr) { case ip::addr4 => @@ -110,13 +110,7 @@ export fn listen( *portout = addr.1; }; - return alloc(net::stream_listener { - l = net::listener { - accept = &net::stream_accept, - shutdown = &net::stream_shutdown, - }, - fd = sockfd, - }): *net::listener; + return sockfd; }; // Returns the remote address for a given connection, or void if none is diff --git a/net/tcp/listener.ha b/net/tcp/listener.ha @@ -3,14 +3,10 @@ use io; use net; -// Accepts the next connection from a listener. Blocks until a new connection is +// 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(l: *net::listener) (io::file | net::error) = { - return net::accept(l); -}; +export fn accept(sock: io::file) (io::file | net::error) = net::accept(sock); -// Shuts down a [[net::listener]] and frees resources associated with it. This -// is a convenience wrapper around [[net::shutdown]]. -export fn shutdown(l: *net::listener) void = { - return net::shutdown(l); -}; +// Shuts down a listening socket. This is a convenience wrapper around +// [[net::shutdown]]. +export fn shutdown(sock: io::file) void = net::shutdown(sock); diff --git a/net/unix/+freebsd.ha b/net/unix/+freebsd.ha @@ -38,11 +38,11 @@ export fn connect(addr: addr) (io::file | net::error) = { return io::fdopen(sockfd); }; -// Binds a UNIX socket listener to the given path. +// Binds a UNIX socket to the given path. export fn listen( addr: addr, options: listen_option... -) (*net::listener | net::error) = { +) (io::file | net::error) = { let sockaddr = match (to_native(addr)) { case let a: rt::sockaddr => yield a; @@ -75,13 +75,7 @@ export fn listen( case int => void; }; - return alloc(net::stream_listener { - l = net::listener { - accept = &net::stream_accept, - shutdown = &net::stream_shutdown, - }, - fd = sockfd, - }): *net::listener; + return sockfd; }; // Converts a UNIX socket address to a native sockaddr. diff --git a/net/unix/+linux.ha b/net/unix/+linux.ha @@ -39,11 +39,11 @@ export fn connect(addr: addr) (io::file | net::error) = { return io::fdopen(sockfd); }; -// Binds a UNIX socket listener to the given path. +// Binds a UNIX socket to the given path. export fn listen( addr: addr, options: listen_option... -) (*net::listener | net::error) = { +) (io::file | net::error) = { let sockaddr = match (to_native(addr)) { case let a: rt::sockaddr => yield a; @@ -76,13 +76,7 @@ export fn listen( case int => void; }; - return alloc(net::stream_listener { - l = net::listener { - accept = &net::stream_accept, - shutdown = &net::stream_shutdown, - }, - fd = sockfd, - }): *net::listener; + return sockfd; }; // Converts a UNIX socket address to a native sockaddr. diff --git a/net/unix/listener.ha b/net/unix/listener.ha @@ -3,14 +3,10 @@ use io; use net; -// Accepts the next connection from a listener. Blocks until a new connection is +// 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(l: *net::listener) (io::file | net::error) = { - return net::accept(l); -}; +export fn accept(sock: io::file) (io::file | net::error) = net::accept(sock); -// Shuts down a [[net::listener]] and frees resources associated with it. This -// is a convenience wrapper around [[net::shutdown]]. -export fn shutdown(l: *net::listener) void = { - return net::shutdown(l); -}; +// Shuts down a listening socket. This is a convenience wrapper around +// [[net::shutdown]]. +export fn shutdown(sock: io::file) void = net::shutdown(sock); diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -851,14 +851,12 @@ net() { gen_srcs -plinux net \ +linux.ha \ errors.ha \ - listener.ha \ msg.ha gen_ssa -plinux net io os strings net::ip errors rt fmt gen_srcs -pfreebsd net \ +freebsd.ha \ errors.ha \ - listener.ha \ msg.ha gen_ssa -pfreebsd net io os strings net::ip errors rt fmt } diff --git a/stdlib.mk b/stdlib.mk @@ -1383,7 +1383,6 @@ $(HARECACHE)/math/random/math_random-any.ssa: $(stdlib_math_random_any_srcs) $(s stdlib_net_linux_srcs= \ $(STDLIB)/net/+linux.ha \ $(STDLIB)/net/errors.ha \ - $(STDLIB)/net/listener.ha \ $(STDLIB)/net/msg.ha $(HARECACHE)/net/net-linux.ssa: $(stdlib_net_linux_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) @@ -1396,7 +1395,6 @@ $(HARECACHE)/net/net-linux.ssa: $(stdlib_net_linux_srcs) $(stdlib_rt) $(stdlib_i stdlib_net_freebsd_srcs= \ $(STDLIB)/net/+freebsd.ha \ $(STDLIB)/net/errors.ha \ - $(STDLIB)/net/listener.ha \ $(STDLIB)/net/msg.ha $(HARECACHE)/net/net-freebsd.ssa: $(stdlib_net_freebsd_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) @@ -3328,7 +3326,6 @@ $(TESTCACHE)/math/random/math_random-any.ssa: $(testlib_math_random_any_srcs) $( testlib_net_linux_srcs= \ $(STDLIB)/net/+linux.ha \ $(STDLIB)/net/errors.ha \ - $(STDLIB)/net/listener.ha \ $(STDLIB)/net/msg.ha $(TESTCACHE)/net/net-linux.ssa: $(testlib_net_linux_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_rt_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) @@ -3341,7 +3338,6 @@ $(TESTCACHE)/net/net-linux.ssa: $(testlib_net_linux_srcs) $(testlib_rt) $(testli testlib_net_freebsd_srcs= \ $(STDLIB)/net/+freebsd.ha \ $(STDLIB)/net/errors.ha \ - $(STDLIB)/net/listener.ha \ $(STDLIB)/net/msg.ha $(TESTCACHE)/net/net-freebsd.ssa: $(testlib_net_freebsd_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_rt_$(PLATFORM)) $(testlib_fmt_$(PLATFORM))