ref: 1bb9fd59499eb6fb7e8b56e4cee72365074d172e
parent: 5db2c35218596d6aac8410b3fc608471836607c3
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Sep 24 01:02:54 EDT 2015
Update syswrap for plan9. Woo error handling.
--- a/lib/std/dial+plan9.myr
+++ b/lib/std/dial+plan9.myr
@@ -41,30 +41,37 @@
/* Try using the connection server */
dir = fmt("{}/cs", netdir)
- csfd = open(dir, Ordwr)
- if csfd < 0
+ match open(dir, Ordwr)
+ | `Fail e:
clone = fmt("{}/{}/clone", netdir, proto)
- ret = call(clone, rem, netdir)
- slfree(clone)
- if ret == -1
+ match call(clone, rem, netdir)
+ | `Ok fd:
+ std.slfree(clone)
+ -> `Ok fd
+ | `Fail err:
+ std.slfree(clone)
-> `Fail "unable to dial without cs"
- else
- -> `Ok ret
;;
+ | `Ok fd:
+ csfd = fd
;;
slfree(dir)
csaddr = fmt("{}!{}", proto, rem)
- if write(csfd, csaddr) < 0
+ match write(csfd, csaddr)
+ | `Fail m:
close(csfd)
-> `Fail "couldn't blah cs"
+ | `Ok _:
+ /* nothing */
;;
slfree(csaddr)
seek(csfd, 0, 0)
while true
- n = read(csfd, buf[:])
- if n <= 0
+ match read(csfd, buf[:])
+ | `std.Ok _:
+ | `std.Fail e:
break
;;
@@ -75,9 +82,9 @@
addr = buf[i+1:n]
;;
- ret = call(clone, addr, netdir)
- if ret >= 0
- break
+ match call(clone, addr, netdir)
+ | `Ok fd: break
+ | `Fail _: /* nothing */
;;
;;
@@ -88,7 +95,7 @@
-> `Ok ret
}
-const call = {clone, addr, netdir
+const call : (a : byte[:], b : byte[:], c : byte[:] -> result(fd, byte[:])) = {clone, addr, netdir
var namebuf : byte[Maxpath]
var databuf : byte[Maxpath]
var name, base, dpath
@@ -95,16 +102,16 @@
var cfd, datafd
var c, n
- datafd = -1
+ datafd = `Fail "didn't even try to open shit"
c = nsclonestr(clone, netdir)
- cfd = open(c, Ordwr)
- if cfd < 0
- goto cleanup
+ match open(c, Ordwr)
+ | `Fail e: goto cleanup
+ | `Ok fd: cfd = fd
;;
- n = read(cfd, namebuf[:])
- if n < 0
- goto cleanup
+ match read(cfd, namebuf[:])
+ | `Ok fd: /* nothing */
+ | `Fail m: goto cleanup
;;
fput(cfd, "connect {}", addr)
name = strstrip(namebuf[:n])
@@ -113,7 +120,10 @@
| `Some i: base = c[:i]
;;
dpath = bfmt(databuf[:], "{}/{}/data", base, name)
- datafd = open(dpath, Ordwr)
+ match open(dpath, Ordwr)
+ | `Ok fd: datafd = `Ok fd
+ | `Fail m: datafd = `Fail "could not open data"
+ ;;
:cleanup
close(cfd)
slfree(c)
--- a/lib/std/errno+plan9.myr
+++ b/lib/std/errno+plan9.myr
@@ -1,6 +1,11 @@
pkg std =
type errno = int
+ const Enone : errno = 0
const Erange : errno = 1
- const Emisc : errno = 2
+ const Ebadf : errno = 2
const Eexist : errno = 3
+ const Einval : errno = 4
+ const Efault : errno = 5
+ const Eio : errno = 6
+ const Emisc : errno = 40
;;
--- a/lib/std/syswrap+plan9.myr
+++ b/lib/std/syswrap+plan9.myr
@@ -2,6 +2,8 @@
use "option.use"
use "types.use"
+use "errno.use"
+use "result.use"
pkg std =
type fd = sys.fd
@@ -31,19 +33,19 @@
const Odir : fdopt = 0x0 /* no-op on plan9 */
/* fd stuff */
- const open : (path : byte[:], opts : fdopt -> fd)
- const openmode : (path : byte[:], opts : fdopt, mode : int64 -> fd)
- const close : (fd : fd -> int64)
- const creat : (path : byte[:], mode : int64 -> fd)
- const read : (fd : fd, buf : byte[:] -> size)
- const write : (fd : fd, buf : byte[:] -> size)
- const seek : (fd : fd, delta : off, whence : whence -> off)
- const pipe : (fds : fd[2]# -> int64)
- const dup2 : (ofd : fd, nfd : fd -> fd)
+ const open : (path : byte[:], opts : fdopt -> result(fd, errno))
+ const openmode : (path : byte[:], opts : fdopt, mode : int64 -> result(fd, errno))
+ const close : (fd : fd -> errno)
+ const creat : (path : byte[:], mode : int64 -> result(fd, errno))
+ const read : (fd : fd, buf : byte[:] -> result(size, errno))
+ const write : (fd : fd, buf : byte[:] -> result(size, errno))
+ const seek : (fd : fd, delta : off, whence : whence -> result(off, errno))
+ const pipe : (fds : fd[2]# -> errno)
+ const dup2 : (ofd : fd, nfd : fd -> result(fd, errno))
/* useful/portable bits of stat */
- const fmtime : (f : byte[:] -> option(time))
- const fsize : (f : byte[:] -> option(off))
+ const fmtime : (f : byte[:] -> result(time, errno))
+ const fsize : (f : byte[:] -> result(off, errno))
const fexists : (f : byte[:] -> bool)
/* the important bits that uname provides */
@@ -58,9 +60,8 @@
const getpid : ( -> pid)
const suicide : ( -> void)
const fork : (-> pid)
- const execv : (cmd : byte[:], args : byte[:][:] -> int64)
- const execve : (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
- const waitpid : (pid:pid, loc:int32#, opt : int64 -> pid)
+ const execv : (cmd : byte[:], args : byte[:][:] -> errno)
+ const execve : (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> errno)
pkglocal const Canunmap : bool = true
pkglocal const getmem : (sz : size -> byte#)
@@ -67,6 +68,7 @@
pkglocal const freemem : (p : byte#, sz : size -> void)
pkglocal const curtime : (-> time)
pkglocal const p9errstr : (buf : byte[:] -> byte[:])
+ pkglocal const waitpid : (pid:pid, loc:int32#, opt : int64 -> pid)
/* statbuf offsets */
pkglocal const Sizeoff : int64 = 0
@@ -86,7 +88,7 @@
extern const getenvv : (name : byte[:], default : byte[:] -> byte[:])
/* fd stuff */
-const open = {path, opts; -> sys.open(path, opts castto(sys.fdopt)) castto(fd)}
+const open = {path, opts; -> check(sys.open(path, opts castto(sys.fdopt)))}
const openmode = {path, opts, mode;
var fd
@@ -99,7 +101,7 @@
if opts & Oappend != 0
sys.seek(fd, 0, 2)
;;
- -> fd castto(fd)
+ -> check(fd)
}
@@ -113,9 +115,9 @@
var buf : byte[Stringsoff + 512] /* enough space for some strings */
if sys.stat(path, buf[:]) < Stringsoff
- -> `None
+ -> `Fail Emisc
;;
- -> `Some (getle32(buf[Mtimeoff:Mtimeoff + 8]) castto(time))
+ -> `Ok (getle32(buf[Mtimeoff:Mtimeoff + 8]) castto(time))
}
const fsize = {path
@@ -122,9 +124,9 @@
var buf : byte[Stringsoff + 512] /* enough space for some strings */
if sys.stat(path, buf[:]) < Stringsoff
- -> `None
+ -> `Fail Emisc
;;
- -> `Some (getle64(buf[Lengthoff:Lengthoff + 8]) castto(off))
+ -> `Ok (getle64(buf[Lengthoff:Lengthoff + 8]) castto(off))
}
const getsysinfo = {si
@@ -134,12 +136,12 @@
si.arch = getenvv("objtype", "amd64")
}
-const close = {fd; -> sys.close(fd castto(sys.fd)) castto(int64)}
-const read = {fd, buf; -> sys.pread(fd castto(sys.fd), buf, -1) castto(size)}
-const write = {fd, buf; -> sys.pwrite(fd castto(sys.fd), buf, -1) castto(size)}
-const seek = {fd, off, whence; -> sys.seek(fd castto(sys.fd), off castto(sys.off), whence castto(int64)) castto(off)}
-const pipe = {fds; -> sys.pipe(fds castto(sys.fd[2]#)) castto(int64)}
-const dup2 = {ofd, nfd; -> sys.dup(ofd castto(sys.fd), nfd castto(sys.fd)) castto(fd)}
+const close = {fd; -> sys.close(fd castto(sys.fd)) castto(errno)}
+const read = {fd, buf; -> check(sys.pread(fd castto(sys.fd), buf, -1))}
+const write = {fd, buf; -> check(sys.pwrite(fd castto(sys.fd), buf, -1))}
+const seek = {fd, off, whence; -> check(sys.seek(fd castto(sys.fd), off castto(sys.off), whence castto(int64)))}
+const pipe = {fds; -> sys.pipe(fds castto(sys.fd[2]#)) castto(errno)}
+const dup2 = {ofd, nfd; -> check(sys.dup(ofd castto(sys.fd), nfd castto(sys.fd)))}
/* path manipulation */
const remove = {path; -> sys.remove(path) == 0}
@@ -159,8 +161,14 @@
const getpid = {; -> sys.tosptr.pid castto(pid)}
const suicide = {; (0 castto(byte#))#} /* let's happy segfault!! t */
const fork = {; -> sys.rfork(sys.Rffdg | sys.Rfrend | sys.Rfproc) castto(pid)}
-const execv = {cmd, args; -> sys.exec(cmd, args) castto(int64)}
-const execve = {cmd, args, env; -> sys.exec(cmd, args) castto(int64)}
+const execv = {cmd, args;
+ sys.exec(cmd, args)
+ -> lasterr()
+}
+const execve = {cmd, args, env;
+ sys.exec(cmd, args)
+ -> lasterr()
+}
/* memory stuff */
const getmem = {sz
@@ -217,4 +225,15 @@
| ((buf[5] castto(int64)) << 40) \
| ((buf[6] castto(int64)) << 48) \
| ((buf[7] castto(int64)) << 56)
+}
+generic check = {e : @a::(integral, numeric) -> result(@b, errno)
+ if e < 0
+ -> `Fail lasterr()
+ else
+ -> `Ok e castto(@b)
+ ;;
+}
+
+const lasterr = {
+ -> Emisc
}