ref: b33507bdac290ffd2792dafeb7b73f81cb4cda8d
parent: 8728342de349e7029312ddbd33c2710d2d03fff2
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Oct 4 17:32:26 EDT 2015
Actually return the error that occurred.
--- a/lib/bio/bio.myr
+++ b/lib/bio/bio.myr
@@ -10,7 +10,7 @@
/* backing fd */
fd : std.fd
mode : mode
- haderr : bool
+ lasterr : std.errno
/* read buffer */
rbuf : byte[:]
@@ -25,9 +25,16 @@
type status(@a) = union
`Eof
`Ok @a
- `Err
+ `Err ioerr
;;
+ type ioerr = union
+ `Ebadfile
+ `Ebadbuf
+ `Ebadfd
+ `Eioerr
+ ;;
+
/* creation */
const mkfile : (fd : std.fd, mode : mode -> file#)
const open : (path : byte[:], mode : mode -> std.result(file#, byte[:]))
@@ -58,7 +65,7 @@
const readln : (f : file# -> status(byte[:]))
const readto : (f : file#, delim : byte[:] -> status(byte[:]))
const skipto : (f : file#, delim : byte[:] -> bool)
- const skipspace : (f : file# -> void)
+ const skipspace : (f : file# -> bool)
/* formatted i/o */
const put : (f : file#, fmt : byte[:], args : ... -> status(std.size))
@@ -66,7 +73,6 @@
/* pkg funcs */
pkglocal const ensureread : (f : file#, n : std.size -> status(std.size))
pkglocal const ensurewrite : (f : file#, n : std.size -> status(std.size))
- pkglocal const writebuf : (fd : std.fd, b : byte[:] -> status(std.size))
;;
const Bufsz = 16*std.KiB
@@ -80,6 +86,7 @@
f.fd = fd
f.mode = mode
+ f.lasterr = 0
if mode & Rd != 0
f.rbuf = std.slalloc(Bufsz)
f.rstart = 0
@@ -182,14 +189,12 @@
returning the number of bytes read.
*/
const read = {f, dst
- var n
- var d
+ var n, d
var count
/* Clear the error state so we can retry */
- if f.haderr
- f.haderr = false
- -> `Err
+ if f.lasterr != 0
+ -> `Err geterr(f)
;;
std.assert(f.mode & Rd != 0, "File is not in read mode")
/*
@@ -218,7 +223,7 @@
break
elif n < 0
if count > 0
- f.haderr = true
+ f.lasterr = n castto(std.errno)
;;
break
;;
@@ -226,7 +231,7 @@
d = d[n:]
;;
if n < 0 && count == 0
- -> `Err
+ -> `Err errtype(n)
elif count == 0
-> `Eof
else
@@ -259,8 +264,8 @@
/* writes a single byte to the output stream */
const putb = {f, b
match ensurewrite(f, 1)
- | `Err: -> `Err
| `Eof: -> `Eof
+ | `Err e: -> `Err e
| `Ok n:
f.wbuf[f.wend++] = b
-> `Ok 1
@@ -273,8 +278,8 @@
sz = std.charlen(c)
match ensurewrite(f, sz)
- | `Err: -> `Err
| `Eof: -> `Eof
+ | `Err e: -> `Err e
| `Ok n:
std.encode(f.wbuf[f.wend:], c)
f.wend += sz
@@ -286,7 +291,7 @@
const getb = {f
match ensureread(f, 1)
| `Eof: -> `Eof
- | `Err: -> `Err
+ | `Err e: -> `Err e
| `Ok n:
-> `Ok f.rbuf[f.rstart++]
;;
@@ -297,8 +302,8 @@
var c
match ensurecodepoint(f)
- | `Err: -> `Err
| `Eof: -> `Eof
+ | `Err e: -> `Err e
| `Ok n:
c = std.decode(f.rbuf[f.rstart:f.rend])
f.rstart += std.charlen(c)
@@ -312,8 +317,8 @@
var len
match ensureread(f, 1)
- | `Err: -> `Err
| `Eof: -> `Eof
+ | `Err e: -> `Err e
| `Ok n:
b = f.rbuf[f.rstart]
if b & 0x80 == 0 /* 0b0xxx_xxxx */
@@ -359,7 +364,7 @@
const peekb = {f
match ensureread(f, 1)
| `Eof: -> `Eof
- | `Err: -> `Err
+ | `Err e: -> `Err e
| `Ok n:
-> `Ok f.rbuf[f.rstart]
;;
@@ -369,7 +374,7 @@
const peekc = {f
match ensurecodepoint(f)
| `Eof: -> `Eof
- | `Err: -> `Err
+ | `Err e: -> `Err e
| `Ok n:
-> `Ok std.decode(f.rbuf[f.rstart:f.rend])
;;
@@ -393,7 +398,7 @@
match readdelim(f, delim, true)
| `Ok ign: -> true
| `Eof: -> false
- | `Err: -> false
+ | `Err _: -> false
;;
}
@@ -401,16 +406,16 @@
while true
match bio.peekc(f)
| `Ok c:
- if std.isspace(c)
+ if !std.isspace(c)
break
;;
bio.getc(f)
- | `Eof:
- break
- | `Err:
- break
+ | `Err e: -> false
+ | `Eof: break
+
;;
;;
+ -> true
}
/* Same as delim, but with special handling for '\n', '\r', and '\r\n' */
@@ -422,7 +427,7 @@
/* get at least delimiter count of characters */
match ensureread(f, 1)
| `Ok _:
- | `Err: -> `Err
+ | `Err e: -> `Err e
| `Eof:
ret = readinto(f, ret, f.rend - f.rstart)
if ret.len > 0
@@ -466,7 +471,7 @@
/* get at least delimiter count of characters */
match ensureread(f, 1)
| `Ok _:
- | `Err: -> `Err
+ | `Err e: -> `Err e
| `Eof:
if !drop
ret = readinto(f, ret, f.rend - f.rstart)
@@ -474,7 +479,7 @@
if ret.len > 0
-> `Ok ret
else
- -> `Err
+ -> `Eof
;;
;;
for var i = f.rstart; i < f.rend; i++
@@ -536,8 +541,8 @@
| `Ok len:
f.wend = 0
-> `Ok len
- | _:
- -> `Err
+ | `Err e: -> `Err e
+ | `Eof: -> `Eof
;;
;;
-> `Ok n
@@ -563,7 +568,7 @@
;;
match fill(f, n)
| `Eof: -> `Eof
- | `Err: -> `Err
+ | `Err e: -> `Err e
| `Ok len:
if len > n
-> `Ok len
@@ -587,7 +592,7 @@
if n == 0
-> `Eof
elif n < 0
- -> `Err
+ -> `Err errtype(n)
;;
count += n
src = src[n:]
@@ -608,9 +613,8 @@
count = 0
/* Clear the error state so we can retry */
- if f.haderr
- f.haderr = false
- -> `Err
+ if f.lasterr != 0
+ -> `Err geterr(f)
;;
while count < min
n = std.read(f.fd, f.rbuf[f.rend:])
@@ -623,7 +627,7 @@
break
elif n < 0
if count > 0
- f.haderr = true
+ f.lasterr = n castto(std.errno)
;;
break
;;
@@ -632,11 +636,36 @@
;;
if n < 0 && count == 0
- -> `Err
+ -> `Err errtype(n)
elif count == 0
-> `Eof
else
-> `Ok count
+ ;;
+}
+
+const geterr = {f
+ var e
+
+ e = f.lasterr
+ f.lasterr = 0
+ -> errtype(e castto(std.size))
+}
+
+const errtype : (e : std.size -> ioerr )= {e : std.size -> ioerr
+ var errno
+
+ errno = e castto(std.errno)
+ if errno == std.Ebadf
+ -> `Ebadfile
+ elif errno == std.Einval
+ -> `Ebadfile
+ elif errno == std.Efault
+ -> `Ebadbuf
+ elif errno == std.Eio
+ -> `Eioerr
+ else
+ -> `Eioerr
;;
}
--- a/lib/bio/geti.myr
+++ b/lib/bio/geti.myr
@@ -26,7 +26,7 @@
v = 0
match ensureread(f, n)
| `Eof: -> `Eof
- | `Err: -> `Err
+ | `Err e : -> `Err e
| `Ok _:
for i = 0; i < n; i++
v |= (f.rbuf[f.rstart++] castto(uint64)) << (8*(i castto(uint64)))
@@ -45,7 +45,7 @@
v = 0
match ensureread(f, n)
| `Eof: -> `Eof
- | `Err: -> `Err
+ | `Err e : -> `Err e
| `Ok _:
for i = 0; i < n; i++
v <<= 8
--- a/lib/bio/puti.myr
+++ b/lib/bio/puti.myr
@@ -30,8 +30,8 @@
var buf : byte[8]
match ensurewrite(f, n)
- | `Err: -> `Err
| `Eof: -> `Eof
+ | `Err e: -> `Err e
| `Ok _:
buf[0] = (v >> 0) & 0xff castto(byte)
buf[1] = (v >> 8) & 0xff castto(byte)
@@ -49,8 +49,8 @@
var buf : byte[8]
match ensurewrite(f, n)
- | `Err: -> `Err
| `Eof: -> `Eof
+ | `Err e: -> `Err e
| `Ok _:
buf[0] = (v >> 56) & 0xff castto(byte)
buf[1] = (v >> 48) & 0xff castto(byte)
--- a/lib/std/errno.myr
+++ b/lib/std/errno.myr
@@ -3,6 +3,7 @@
pkg std =
type errno = int
+ const Enone : errno = 0
const Eperm : errno = sys.Eperm castto(errno)
const Enoent : errno = sys.Enoent castto(errno)
const Esrch : errno = sys.Esrch castto(errno)
--- a/lib/std/syserrno+plan9.myr
+++ b/lib/std/syserrno+plan9.myr
@@ -1,6 +1,7 @@
pkg sys =
type errno = int
+ const Enone : errno = 0
const Eperm : errno = -1 /* Operation not permitted */
const Enoent : errno = -2 /* No such file or directory */
const Esrch : errno = -3 /* No such process */
--- a/mbld/deps.myr
+++ b/mbld/deps.myr
@@ -215,7 +215,7 @@
while true
lnum++
match bio.readln(f)
- | `bio.Err: std.fatal("unable to read {}\n", path)
+ | `bio.Err e: std.fatal("unable to read {}: {}\n", path, e)
| `bio.Eof: break
| `bio.Ok ln:
(cflags, libs) = getcflags(ln, cflags, libs)
@@ -261,7 +261,7 @@
while true
lnum++
match bio.readln(f)
- | `bio.Err: std.fatal("unable to read {}\n", path)
+ | `bio.Err e: std.fatal("unable to read {}: {}\n", path, e)
| `bio.Eof: break
| `bio.Ok ln:
deps = depname(deps, ln, lnum)
@@ -318,7 +318,7 @@
match bio.getc(f)
| `bio.Ok 'U': /* nothing */
| `bio.Ok _: std.fatal("library {}: corrupt or invalid usefile\n", lib)
- | `bio.Err: std.fatal("library {}: could not read usefile\n", lib)
+ | `bio.Err e: std.fatal("library {}: could not read usefile: {}\n", lib, e)
| `bio.Eof: std.fatal("library {}: could not read usefile\n", lib)
;;
match bio.getbe32(f)
@@ -329,8 +329,8 @@
else
std.fput(1, "library {}: usefile version {} unknown\n", lib, v)
;;
+ | `bio.Err e: std.fatal("library {}: error reading usefile: {}\n", lib, e)
| `bio.Eof: std.fatal("library {}: corrupt or truncated usefile\n", lib)
- | `bio.Err: std.fatal("library {}: error reading usefile\n", lib)
;;
std.slfree(rdstr(f))
@@ -346,7 +346,7 @@
dg.extlibs = std.slpush(dg.extlibs, d)
| `bio.Ok _: done = true
| `bio.Eof: done = true
- | `bio.Err: std.fatal("io error reading {}", lib)
+ | `bio.Err e: std.fatal("io error reading {}: {}", lib, e)
;;
;;
bio.close(f)
@@ -395,8 +395,8 @@
| `bio.Ok l:
len = l
sl = std.slalloc(len)
- | `bio.Eof: std.die("end of file while reading string")
- | `bio.Err: std.die("error while reading string")
+ | `bio.Eof: std.fatal("end of file while reading string")
+ | `bio.Err e: std.fatal("error while reading string: {}", e)
;;
bio.read(f, sl)
-> sl