shithub: mc

Download patch

ref: bd25454011010946b91c21e8af737d86505c4041
parent: 59d49a9789ad8fae0d464e3e60e1196d7d861d18
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Sep 11 19:27:16 EDT 2017

Add missing listen implementation on plan9.

--- a/lib/std/bld.sub
+++ b/lib/std/bld.sub
@@ -108,6 +108,7 @@
 	env+posixy.myr
 	errno+plan9.myr
 	listen+posixy.myr
+	listen+plan9.myr
 	resolve+plan9.myr
 	resolve+posixy.myr
 	wait+plan9.myr
--- /dev/null
+++ b/lib/std/listen+plan9.myr
@@ -1,0 +1,171 @@
+use sys
+
+use "alloc"
+use "die"
+use "dirname"
+use "fmt"
+use "option"
+use "result"
+use "strfind"
+use "syswrap"
+use "cstrconv"
+use "utf"
+
+pkg std =
+	const announce	: (ds : byte[:] -> result(fd, byte[:]))
+	const accept	: (lfd : fd -> result(fd, byte[:]))
+;;
+
+const Maxpath = 256
+
+const announce = {ds
+	var a, abuf : byte[Maxpath]
+	var f, fbuf : byte[Maxpath]
+	var l, lbuf : byte[Maxpath]
+	var nbuf : byte[32]
+	var dir, ctl, lfd, n
+
+	/* announce */
+	match translate(ds, abuf[:], fbuf[:])
+	| `Err _:	-> `Err "invalid dial string"
+	| `Ok (addr, file):
+		put("addr: {}, file: {}\n", addr, file)
+		a = addr
+		f = file
+		match strrfind(f, "/")
+		| `Some i:	dir = i
+		| `None:	-> `Err "invalid net dir"
+		;;
+	;;
+
+	match open(f, Ordwr)
+	| `Ok fd:	ctl = fd
+	| `Err e:	-> `Err "could not open ctl fd"
+	;;
+
+	match read(ctl, nbuf[:])
+	| `Err e:	->`Err "unable to read ctl fd"
+	| `Ok nn:	l = bfmt(lbuf[:], "{}/{}/listen", f[:dir], nbuf[:nn])
+	;;
+
+	put("announce {}\n", a)
+	n = fput(ctl, "announce {}", a)
+	if n <= 0
+		close(ctl)
+		-> `Err "writing announce"
+	;;
+
+	/* listen */
+	match open(l, Ordwr)
+	| `Err e:
+		close(ctl)
+		-> `Err "could not open ctl"
+	| `Ok fd:
+		lfd = fd
+	;;
+	close(ctl)
+
+	-> `Ok lfd
+}
+
+const accept = {lfd -> result(fd, byte[:])
+	var dir, dirbuf : byte[40]
+	var num, numbuf : byte[40]
+	var dat, datbuf : byte[Maxpath]
+
+
+
+	match read(lfd, numbuf[:])
+	| `Ok n:	num = numbuf[:n]
+	| `Err e:	-> `Err "could not accept"
+	;;
+	fput(lfd, "accept {}", num)
+
+	sys.fd2path((lfd : sys.fd), dirbuf[:])
+	dir = dirname(cstrconv(dirbuf[:]))
+	match strrfind(dir, "/")
+	| `None:	dat = bfmt(datbuf[:], "{}/{}/data", dir, num)
+	| `Some i:	dat = bfmt(datbuf[:], "{}/{}/data", dir[:i], num)
+	;;
+
+	put("data fd: {}\n", dat)
+	match open(dat, Ordwr)
+	| `Ok fd:	-> `Ok fd
+	| `Err e:	-> `Err "could not open data fd"
+	;;
+}
+
+const translate = {ds, addrbuf, filebuf
+	var cs, csbuf : byte[Maxpath]
+	var r, rbuf : byte[Maxpath]
+	var netdir, rest
+	var addr, file
+
+	match strfind(ds, "!")
+	| `None:	-> `Err void
+	| `Some sep:
+		if decode(ds[:sep]) == '#' || decode(ds[:sep]) == '/'
+			match strrfind(ds[:sep], "/")
+			| `None:	-> `Err void
+			| `Some idx:
+				netdir = ds[:idx]
+				rest = ds[idx+1:]
+			;;
+		else
+			netdir = "/net"
+			addr = ds
+		;;
+	;;
+
+	cs = bfmt(csbuf[:], "{}/cs", netdir)
+	match open(cs, Ordwr)
+	| `Err e:	-> identtrans(rest, netdir, addrbuf, filebuf)
+	| `Ok fd:
+		match write(fd, addr)
+		| `Err e:
+			close(fd)
+			-> `Err void
+		| `Ok _:
+		;;
+
+		seek(fd, 0, Seekset)
+		match read(fd, rbuf[:])
+		| `Err e:
+			close(fd)
+			-> `Err void
+		| `Ok n:
+			r = rbuf[:n]
+		;;
+		close(fd)
+	;;
+
+	put("cs returned: {}\n", r)
+	match strfind(r, " ")
+	| `None:	-> `Err void
+	| `Some i:
+		addr = bfmt(addrbuf, "{}", r[i+1:])
+		if decode(r) == '/'
+			match strfind(r[:i], "/")
+			| `None:	-> `Err void
+			| `Some 0:	file = bfmt(filebuf, "{}{}", netdir, r[:i])
+			| `Some n:	file = bfmt(filebuf, "{}{}", netdir, r[n+1:])
+			;;
+		else
+			file = bfmt(filebuf, "{}/{}", netdir, r[:i])
+		;;
+	;;
+	-> `Ok (addr, file) 
+}
+
+const identtrans = {ds, netdir, addrbuf, filebuf
+	var a, f
+
+	match strfind(ds, "!")
+	| `None:
+		-> `Err void
+	| `Some sep:
+		a = bfmt(addrbuf, "{}", ds[sep + 1:])
+		f = bfmt(filebuf, "{}/{}/clone", netdir, ds[:sep])
+		-> `Ok (a, f)
+	;;
+}