commit 63d7991a6acfbee0b340e7528dc250b4dd3885ff
parent af36e75cce23185e00818781df34c4f956def163
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 1 Feb 2021 14:17:42 -0500
io: distinguish between closed and EOF conditions
Diffstat:
4 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/io/copy.ha b/io/copy.ha
@@ -5,10 +5,7 @@ export fn copy(dest: *stream, src: *stream) (error | size) = {
let buf: [4096]u8 = [0u8...];
for (true) {
match (read(src, buf[..])) {
- err: error => match (err) {
- closed => break,
- * => return err,
- },
+ err: error => return err,
n: size => match (write(dest, buf[..n])) {
err: error => return err,
r: size => {
@@ -16,6 +13,7 @@ export fn copy(dest: *stream, src: *stream) (error | size) = {
w += n;
},
},
+ EOF => break,
};
};
return w;
diff --git a/io/stream.ha b/io/stream.ha
@@ -28,7 +28,7 @@ export type stream = struct {
// Reads up to len(buf) bytes from the reader into the given buffer, returning
// the number of bytes read.
-export fn read(s: *stream, buf: []u8) (size | error) = {
+export fn read(s: *stream, buf: []u8) (size | EOF | error) = {
return match (s.reader) {
null => unsupported: error,
r: *reader => r(s, buf),
diff --git a/io/types.ha b/io/types.ha
@@ -13,6 +13,9 @@ export type unsupported = void;
// Any error which may be returned from an I/O function.
export type error = (os_error | closed | unsupported);
+// Indicates an end-of-file condition.
+export type EOF = void;
+
// Converts an I/O error into a user-friendly string.
export fn errstr(err: error) str = {
return match (err) {
@@ -31,7 +34,7 @@ export type mode = enum uint {
// The interface for a stream which can be read from. Reads up to len(buf)
// bytes from the reader into the given buffer, returning the number of bytes
// read or an error.
-export type reader = fn(s: *stream, buf: []u8) (size | error);
+export type reader = fn(s: *stream, buf: []u8) (size | EOF | error);
// The interface for a stream which can be written to. Writes up to len(buf)
// bytes to the writer from the given buffer, returning the number of bytes
diff --git a/os/+linux/fdstream.ha b/os/+linux/fdstream.ha
@@ -44,14 +44,15 @@ fn static_fdopen(fd: int, name: str, stream: *fd_stream) void = {
stream.fd = fd;
};
-fn fd_read(s: *io::stream, buf: []u8) (size | io::error) = {
+fn fd_read(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = {
let stream = s: *fd_stream;
let r = rt::read(stream.fd, (&buf: *types::slice).data: *[*]u8, len(buf));
return match (rt::wrap_return(r)) {
err: rt::errno => errno_to_io(err),
n: size => switch (n) {
- 0z => io::closed: io::error,
- * => n,
+ // TODO: Fix me when swich is fixed up
+ 0z => io::EOF: (size | io::EOF | io::error),
+ * => n: (size | io::EOF | io::error),
},
};
};