From b33507bdac290ffd2792dafeb7b73f81cb4cda8d Mon Sep 17 00:00:00 2001 From: Ori Bernstein Date: Sun, 4 Oct 2015 21:32:26 -0700 Subject: Actually return the error that occurred. --- lib/bio/bio.myr | 101 +++++++++++++++++++++++++++++---------------- lib/bio/geti.myr | 4 +- lib/bio/puti.myr | 4 +- lib/std/errno.myr | 1 + lib/std/syserrno+plan9.myr | 1 + mbld/deps.myr | 14 +++---- 6 files changed, 78 insertions(+), 47 deletions(-) diff --git a/lib/bio/bio.myr b/lib/bio/bio.myr index 8e8e9fe..eae9137 100644 --- a/lib/bio/bio.myr +++ b/lib/bio/bio.myr @@ -10,7 +10,7 @@ pkg bio = /* backing fd */ fd : std.fd mode : mode - haderr : bool + lasterr : std.errno /* read buffer */ rbuf : byte[:] @@ -25,7 +25,14 @@ pkg bio = type status(@a) = union `Eof `Ok @a - `Err + `Err ioerr + ;; + + type ioerr = union + `Ebadfile + `Ebadbuf + `Ebadfd + `Eioerr ;; /* creation */ @@ -58,7 +65,7 @@ pkg bio = 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 bio = /* 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 @@ const mkfile = {fd, mode 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 @@ reads as much into 'dst' as possible, up to the size of 'dst', 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 @@ const read = {f, dst break elif n < 0 if count > 0 - f.haderr = true + f.lasterr = n castto(std.errno) ;; break ;; @@ -226,7 +231,7 @@ const read = {f, dst d = d[n:] ;; if n < 0 && count == 0 - -> `Err + -> `Err errtype(n) elif count == 0 -> `Eof else @@ -259,8 +264,8 @@ const seek = {f, off /* 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 @@ const putc = {f, c 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 putc = {f, c 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 @@ const getc = {f 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 @@ const ensurecodepoint : (f : file# -> status(std.size)) = {f 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 @@ generic putbe = {f, v : @a::(numeric,integral) 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 peekb = {f 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 @@ const skipto = {f, delim match readdelim(f, delim, true) | `Ok ign: -> true | `Eof: -> false - | `Err: -> false + | `Err _: -> false ;; } @@ -401,16 +406,16 @@ const skipspace = {f 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 @@ const readln = {f /* 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 @@ const readdelim = {f, delim, drop /* 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 @@ const readdelim = {f, delim, drop if ret.len > 0 -> `Ok ret else - -> `Err + -> `Eof ;; ;; for var i = f.rstart; i < f.rend; i++ @@ -536,8 +541,8 @@ const ensurewrite = {f, n | `Ok len: f.wend = 0 -> `Ok len - | _: - -> `Err + | `Err e: -> `Err e + | `Eof: -> `Eof ;; ;; -> `Ok n @@ -563,7 +568,7 @@ const ensureread = {f, n ;; match fill(f, n) | `Eof: -> `Eof - | `Err: -> `Err + | `Err e: -> `Err e | `Ok len: if len > n -> `Ok len @@ -587,7 +592,7 @@ const writebuf = {fd, src if n == 0 -> `Eof elif n < 0 - -> `Err + -> `Err errtype(n) ;; count += n src = src[n:] @@ -608,9 +613,8 @@ const fill = {f, min 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 @@ const fill = {f, min break elif n < 0 if count > 0 - f.haderr = true + f.lasterr = n castto(std.errno) ;; break ;; @@ -632,7 +636,7 @@ const fill = {f, min ;; if n < 0 && count == 0 - -> `Err + -> `Err errtype(n) elif count == 0 -> `Eof else @@ -640,4 +644,29 @@ const fill = {f, min ;; } +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 + ;; +} + diff --git a/lib/bio/geti.myr b/lib/bio/geti.myr index ce20219..5752f9c 100644 --- a/lib/bio/geti.myr +++ b/lib/bio/geti.myr @@ -26,7 +26,7 @@ generic getle = {f, n -> status(@a::(numeric,integral)) 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 @@ generic getbe = {f, n -> status(@a::(numeric,integral)) v = 0 match ensureread(f, n) | `Eof: -> `Eof - | `Err: -> `Err + | `Err e : -> `Err e | `Ok _: for i = 0; i < n; i++ v <<= 8 diff --git a/lib/bio/puti.myr b/lib/bio/puti.myr index 035a1ba..578279a 100644 --- a/lib/bio/puti.myr +++ b/lib/bio/puti.myr @@ -30,8 +30,8 @@ const putle = {f, v, n 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 @@ const putbe = {f, v, n 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) diff --git a/lib/std/errno.myr b/lib/std/errno.myr index c14c469..ff02176 100644 --- a/lib/std/errno.myr +++ b/lib/std/errno.myr @@ -3,6 +3,7 @@ use sys 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) diff --git a/lib/std/syserrno+plan9.myr b/lib/std/syserrno+plan9.myr index 18a3fc2..b58ca00 100644 --- 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 */ diff --git a/mbld/deps.myr b/mbld/deps.myr index 296ea60..c8790e3 100644 --- a/mbld/deps.myr +++ b/mbld/deps.myr @@ -215,7 +215,7 @@ const scrapecflags = {b, ds, path 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 @@ const getdeps = {b, ds, path 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 @@ const scrapelibs = {dg, lib, incs 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 @@ const scrapelibs = {dg, lib, incs 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 @@ const scrapelibs = {dg, lib, incs 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 @@ const rdstr = {f | `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 -- cgit v1.1