shithub: mc

Download patch

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