code: plan9front

Download patch

ref: 87160cbfcf926fd0a9f04e8113a16c2a0c7e252d
parent: 63f10d4c945e3e692b589175508b95ce8dd9b50d
author: Jacob Moody <moody@posixcafe.org>
date: Sat Sep 10 21:49:01 EDT 2022

rio: add 'none' attach option to wsys

This allows users to mount wsys without having
a valid window or creating a new one. In this
mode wsys only servs 'global' files, those that
apply to all windows. Providing this mount to
riostart's namespace gives us two things:

* Allows kbdtap programs(ktrans) to run in riostart
* Obsoletes $wctl and the associated named pipe by providing /dev/wctl in riostart

As such, the wctl pipe and environment variable are removed as well.

--- a/sys/src/cmd/rio/dat.h
+++ b/sys/src/cmd/rio/dat.h
@@ -1,6 +1,13 @@
 enum
 {
 	Qdir,			/* /dev for this window */
+	Qscreen,
+	Qsnarf,
+	Qwctl,
+	Qtap,
+	Qwsys,		/* directory of window directories */
+	Qwsysdir,		/* window directory, child of wsys */
+
 	Qcons,
 	Qconsctl,
 	Qcursor,
@@ -10,17 +17,11 @@
 	Qlabel,
 	Qkbd,
 	Qmouse,
-	Qnew,
-	Qscreen,
-	Qsnarf,
 	Qtext,
-	Qwctl,
 	Qwindow,
-	Qwsys,		/* directory of window directories */
-	Qwsysdir,		/* window directory, child of wsys */
-	Qtap,
 
 	QMAX,
+	Qglobal = Qcons,	/* anything >= must have non nil window */
 };
 
 #define	STACK	8192
@@ -271,9 +272,6 @@
 Xfid*		filsysrespond(Filsys*, Xfid*, Fcall*, char*);
 void		filsyscancel(Xfid*);
 
-void		wctlproc(void*);
-void		wctlthread(void*);
-
 void		deletetimeoutproc(void*);
 
 struct Timer
@@ -337,7 +335,6 @@
 Channel*	winclosechan;
 char		*startdir;
 int		sweeping;
-int		wctlfd;
 char		srvpipe[];
 char		srvwctl[];
 int		errorshouldabort;
--- a/sys/src/cmd/rio/fsys.c
+++ b/sys/src/cmd/rio/fsys.c
@@ -22,6 +22,12 @@
 Dirtab dirtab[]=
 {
 	{ ".",			QTDIR,	Qdir,			0500|DMDIR },
+	{ "screen",		QTFILE,	Qscreen,		0400 },
+	{ "snarf",		QTFILE,	Qsnarf,		0600 },
+	{ "wctl",		QTFILE,	Qwctl,		0600 },
+	{ "kbdtap",	QTFILE,	Qtap,	0660 },
+	{ "wsys",		QTDIR,	Qwsys,		0500|DMDIR },
+
 	{ "cons",		QTFILE,	Qcons,		0600 },
 	{ "cursor",		QTFILE,	Qcursor,		0600 },
 	{ "consctl",	QTFILE,	Qconsctl,		0200 },
@@ -30,14 +36,9 @@
 	{ "label",		QTFILE,	Qlabel,		0600 },
 	{ "kbd",	QTFILE,	Qkbd,		0600 },
 	{ "mouse",	QTFILE,	Qmouse,		0600 },
-	{ "screen",		QTFILE,	Qscreen,		0400 },
-	{ "snarf",		QTFILE,	Qsnarf,		0600 },
 	{ "text",		QTFILE,	Qtext,		0600 },
 	{ "wdir",		QTFILE,	Qwdir,		0600 },
-	{ "wctl",		QTFILE,	Qwctl,		0600 },
 	{ "window",	QTFILE,	Qwindow,		0400 },
-	{ "wsys",		QTDIR,	Qwsys,		0500|DMDIR },
-	{ "kbdtap",	QTFILE,	Qtap,	0660 },
 	{ nil, }
 };
 
@@ -119,9 +120,7 @@
 Filsys*
 filsysinit(Channel *cxfidalloc)
 {
-	int p0;
 	Filsys *fs;
-	Channel *c;
 
 	fs = emalloc(sizeof(Filsys));
 	if(cexecpipe(&fs->cfd, &fs->sfd) < 0)
@@ -134,28 +133,7 @@
 		error("chancreate syncflush");
 	fs->cxfidalloc = cxfidalloc;
 
-	/*
-	 * Create and post wctl pipe
-	 */
-	if(cexecpipe(&p0, &wctlfd) < 0)
-		goto Rescue;
-	snprint(srvwctl, sizeof(srvwctl), "/srv/riowctl.%s.%lud", fs->user, (ulong)getpid());
-	post(srvwctl, "wctl", p0);
-	close(p0);
-
-	/*
-	 * Start server processes
-	 */
-	c = chancreate(sizeof(char*), 0);
-	if(c == nil)
-		error("wctl channel");
-	proccreate(wctlproc, c, 4096);
-	threadcreate(wctlthread, c, 4096);
 	proccreate(filsysproc, fs, 10000);
-
-	/*
-	 * Post srv pipe
-	 */
 	snprint(srvpipe, sizeof(srvpipe), "/srv/rio.%s.%lud", fs->user, (ulong)getpid());
 	post(srvpipe, "wsys", fs->cfd);
 
@@ -385,7 +363,8 @@
 		nf->dir = f->dir;
 		nf->qid = f->qid;
 		nf->w = f->w;
-		incref(f->w);
+		if(f->w != nil)
+			incref(f->w);
 		nf->nrpart = 0;	/* not open, so must be zero */
 		f = nf;	/* walk f */
 	}
@@ -450,6 +429,8 @@
 			d++;	/* skip '.' */
 			for(; d->name; d++)
 				if(strcmp(x->wname[i], d->name) == 0){
+					if(f->w == nil && d->qid >= Qglobal)
+						break;
 					path = d->qid;
 					type = d->type;
 					dir = d;
@@ -560,6 +541,8 @@
 		d++;	/* first entry is '.' */
 		for(i=0; d->name!=nil && i<e; d++){
 			if(skipdir(d->name))
+				continue;
+			if(f->w == nil && d->qid >= Qglobal)
 				continue;
 			len = dostat(fs, WIN(x->f->qid), d, b+n, x->count-n, clock);
 			if(len <= BIT16SZ)
--- a/sys/src/cmd/rio/rio.c
+++ b/sys/src/cmd/rio/rio.c
@@ -293,9 +293,21 @@
 initcmd(void *arg)
 {
 	char *cmd;
+	char *wsys;
+	int fd;
 
 	cmd = arg;
 	rfork(RFENVG|RFFDG|RFNOTEG|RFNAMEG);
+	wsys = getenv("wsys");
+	fd = open(wsys, ORDWR);
+	if(fd < 0)
+		fprint(2, "rio: failed to open wsys: %r\n");
+	if(mount(fd, -1, "/mnt/wsys", MREPL, "none") < 0)
+		fprint(2, "rio: failed to mount wsys: %r\n");
+	if(bind("/mnt/wsys", "/dev/", MBEFORE) < 0)
+		fprint(2, "rio: failed to bind wsys: %r\n");
+	free(wsys);
+	close(fd);
 	procexecl(nil, "/bin/rc", "rc", "-c", cmd, nil);
 	fprint(2, "rio: exec failed: %r\n");
 	exits("exec");
--- a/sys/src/cmd/rio/wctl.c
+++ b/sys/src/cmd/rio/wctl.c
@@ -462,7 +462,10 @@
 	x->data[cnt] = '\0';
 	id = 0;
 
-	r = rectsubpt(w->screenr, screen->r.min);
+	if(w == nil)
+		r = ZR;
+	else
+		r = rectsubpt(w->screenr, screen->r.min);
 	cmd = parsewctl(&arg, r, &r, &pid, &id, &hideit, &scrollit, &dir, x->data, err);
 	if(cmd < 0)
 		return -1;
@@ -475,6 +478,11 @@
 		}
 	}
 
+	if(w == nil && cmd != New){
+		strcpy(err, "command needs to be run within a window");
+		return -1;
+	}
+
 	switch(cmd){
 	case New:
 		return wctlnew(r, arg, pid, hideit, scrollit, dir, err);
@@ -489,57 +497,4 @@
 	wclose(w);
 
 	return id;
-}
-
-void
-wctlthread(void *v)
-{
-	char *buf, *arg, *dir;
-	int cmd, id, pid, hideit, scrollit;
-	Rectangle rect;
-	char err[ERRMAX];
-	Channel *c;
-
-	c = v;
-
-	threadsetname("WCTLTHREAD");
-
-	for(;;){
-		buf = recvp(c);
-		cmd = parsewctl(&arg, ZR, &rect, &pid, &id, &hideit, &scrollit, &dir, buf, err);
-
-		switch(cmd){
-		case New:
-			wctlnew(rect, arg, pid, hideit, scrollit, dir, err);
-		}
-		free(buf);
-	}
-}
-
-void
-wctlproc(void *v)
-{
-	char *buf;
-	int n, eofs;
-	Channel *c;
-
-	threadsetname("WCTLPROC");
-	c = v;
-
-	eofs = 0;
-	for(;;){
-		buf = emalloc(messagesize);
-		n = read(wctlfd, buf, messagesize-1);	/* room for \0 */
-		if(n < 0)
-			break;
-		if(n == 0){
-			if(++eofs > 20)
-				break;
-			continue;
-		}
-		eofs = 0;
-
-		buf[n] = '\0';
-		sendp(c, buf);
-	}
 }
--- a/sys/src/cmd/rio/xfid.c
+++ b/sys/src/cmd/rio/xfid.c
@@ -221,6 +221,9 @@
 			err = errbuf;
 		else
 			goto Allocate;
+	}else if(strncmp(x->aname, "none", 4) == 0){
+		x->f->w = nil;
+		goto Done;
 	}else{
 		id = atoi(x->aname);
 		w = wlookid(id);
@@ -234,6 +237,7 @@
 	}
 	if(!newlymade)	/* counteract dec() in winshell() */
 		incref(w);
+  Done:
 	qunlock(&all);
 	filsysrespond(x->fs, x, &t, nil);
 }
@@ -245,7 +249,7 @@
 	Window *w;
 
 	w = x->f->w;
-	if(w->deleted){
+	if(w != nil && w->deleted){
 		filsysrespond(x->fs, x, &t, Edeleted);
 		return;
 	}
@@ -368,7 +372,8 @@
 		chanprint(ctltap, "%c", Tapoff);
 		break;
 	}
-	wclose(w);
+	if(w)
+		wclose(w);
 	filsysrespond(x->fs, x, &t, nil);
 }
 
@@ -387,7 +392,7 @@
 	Alt alts[NCW+1];
 
 	w = x->f->w;
-	if(w->deleted){
+	if(w != nil && w->deleted){
 		filsysrespond(x->fs, x, &fc, Edeleted);
 		return;
 	}
@@ -642,7 +647,7 @@
 	Alt alts[Aend+1];
 
 	w = x->f->w;
-	if(w->deleted){
+	if(w != nil && w->deleted){
 		filsysrespond(x->fs, x, &fc, Edeleted);
 		return;
 	}
@@ -651,6 +656,10 @@
 	cnt = x->count;
 	switch(qid){
 	case Qwctl:
+		if(w == nil){
+			filsysrespond(x->fs, x, &fc, "no window");
+			return;
+		}
 		if(cnt < 4*12){
 			filsysrespond(x->fs, x, &fc, Etooshort);
 			return;
@@ -703,9 +712,12 @@
 		alts[Adata].c = totap;
 		alts[Adata].v = &t;
 		alts[Adata].op = CHANRCV;
-		alts[Agone].c = w->gone;
-		alts[Agone].v = nil;
-		alts[Agone].op = CHANRCV;
+		if(w != nil){
+			alts[Agone].c = w->gone;
+			alts[Agone].v = nil;
+			alts[Agone].op = CHANRCV;
+		} else
+			alts[Agone].op = CHANNOP;
 		alts[Aflush].c = x->flushc;
 		alts[Aflush].v = nil;
 		alts[Aflush].op = CHANRCV;