hare

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

commit 652f7aa04033bb6091378168fb45ce6970f72473
parent 64f03254705d37d95ccde4040c9d5b07716b3bd4
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue,  2 Feb 2021 16:14:37 -0500

io::copy: use io::unsupported to force fallback

Diffstat:
Mio/copy.ha | 8+++++++-
Mio/types.ha | 6++++--
Mos/+linux/fdstream.ha | 14+++++---------
3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/io/copy.ha b/io/copy.ha @@ -3,7 +3,13 @@ export fn copy(dest: *stream, src: *stream) (error | size) = { match (dest.copier) { null => void, - c: *copier => return c(dest, src), + c: *copier => match (c(dest, src)) { + err: error => match (err) { + unsupported => void, // Use fallback + * => return err, + }, + s: size => return s, + }, }; let w = 0z; diff --git a/io/types.ha b/io/types.ha @@ -53,6 +53,8 @@ export type closer = fn(s: *stream) void; // with a stream which does not implement this (it falls back to calling read // and write in a loop). // -// Returns the number of bytes copied, or an error if one occured. Does not -// close either stream. +// Returns the number of bytes copied, or an error if one occured. Do not close +// either stream. If the operation is unsupported for this particular pair of +// streams, return [io::unsupported] to have [io::copy] proceed with its +// fallback implementation. export type copier = fn(to: *stream, from: *stream) (size | error); diff --git a/os/+linux/fdstream.ha b/os/+linux/fdstream.ha @@ -91,7 +91,7 @@ def SENDFILE_MAX: size = 2147479552z; fn fd_copy(_to: *io::stream, _from: *io::stream) (size | io::error) = { if (!is_fdstream(_from)) { - return copy_fallback(_to, _from); + return io::unsupported; }; let to = _to: *fd_stream, from = _from: *fd_stream; @@ -102,8 +102,10 @@ fn fd_copy(_to: *io::stream, _from: *io::stream) (size | io::error) = { let n = match(rt::wrap_return(r)) { err: rt::errno => switch (err) { rt::EINVAL => { - assert(sum == 0z); - return copy_fallback(_to, _from); + if (sum == 0z) { + return io::unsupported; + }; + return errno_to_io(err); }, * => return errno_to_io(err), }, @@ -119,9 +121,3 @@ fn fd_copy(_to: *io::stream, _from: *io::stream) (size | io::error) = { }; return sum; }; - -fn copy_fallback(_to: *io::stream, _from: *io::stream) (size | io::error) = { - let to = _to: *fd_stream, temp = *to; - temp.stream.copier = null; - return io::copy(&temp.stream, _from); -};