Plan 9 from Bell Labs’s /usr/web/sources/contrib/rog/infauth/unpacked/appl/authsrc/winsrv.b

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


implement Newwin;
# serve /n/rwin/new, allowing new shell windows to be created
# by remote agents. assumes mntgen on /n.
# write kind of window to be created into /n/rwin/new (sh or rio); read name of directory
# containing cons/consctl, etc

include "sys.m";
	sys: Sys;
include "draw.m";
include "sh.m";
	sh: Sh;

Newwin: module {
	init: fn(nil: ref Draw->Context, nil: list of string);
};

init(ctxt: ref Draw->Context, nil: list of string)
{
	sys = load Sys Sys->PATH;
	sh = load Sh Sh->PATH;

	sys->pipe(p := array[2] of ref Sys->FD);
	spawn srv(ctxt, p[0], sync := chan of int);
	p[0] = nil;
	<-sync;
	if(sys->mount(p[1], nil, "/n/rwin", Sys->MREPL, nil) == -1)
		raise "fail:cannot mount";
}

srv(ctxt: ref Draw->Context, fd: ref Sys->FD, sync: chan of int)
{
	sys->pctl(Sys->FORKNS | Sys->FORKFD, nil);
	sync <-= 0;
	spawn export(fd, "/n/rwin");

	sys->bind("#s", "/n/rwin", Sys->MBEFORE);
	sh->run(nil, "mount" :: "-a" :: "{mntgen}" :: "/n/rwin" :: nil);
	fio := sys->file2chan("/n/rwin", "new");
	if(fio == nil){
		sys->print("cannot make /chan/newwin: %r");
		return;
	}
	spawn srv0(ctxt, fio);
}

export(fd: ref Sys->FD, d: string)
{
	sys->export(fd, d, Sys->EXPWAIT);
}

srv0(ctxt: ref Draw->Context, fio: ref Sys->FileIO)
{
	pending: list of (int, array of byte);
loop:
	for(;;)alt{
	(nil, data, fid, wc) := <-fio.write =>
		if(wc == nil)
			break;
		if(len data > 0 && data[len data - 1] == byte '\n')
			data = data[0:len data - 1];
		for(p := pending; p != nil; p = tl p)
			if((hd p).t0 == fid){
				wc <-= (-1, "request already pending");
				continue loop;
			}
		(d, e) := newwin(ctxt, string data);
		if(d == nil)
			wc <-= (-1, sys->sprint("cannot start shell: %s", e));
		else{
			pending = (fid, array of byte d) :: pending;
			wc <-= (len data, nil);
		}
	(offset, nb, fid, rc) := <-fio.read =>
		p: list of (int, array of byte);
		if(rc == nil){
			for(; pending != nil; pending = tl pending)
				if((hd pending).t0 != fid)
					p = hd pending :: p;
			pending = p;
			break;
		}
		d: array of byte;
		for(; pending != nil; pending = tl pending){
			if((hd pending).t0 == fid)
				d = (hd pending).t1;
			else
				p = hd pending :: p;
		}
		if(offset >= len d)
			rc <-= (nil, nil);
		else{
			rc <-= (d, nil);
			if(offset + nb < len d)
				pending = (fid, d) :: pending;
		}
	}
}

n := 0;

newwin(ctxt: ref Draw->Context, kind: string): (string, string)
{
	d := sys->sprint("%d", n++);
	case kind {
	"sh" =>
		e := sh->run(ctxt, "/dis/wm/remotesh" :: "-s" :: "/n/rwin/"+d :: nil);
		if(e != nil)
			return (nil, e);
	"rio" =>
		e := sh->run(ctxt, "9win" :: "-s" :: "/n/rwin/"+d :: nil);
		if(e != nil)
			return (nil, e);
		sys->bind("/dev", "/n/rwin/"+d, Sys->MAFTER);
	* =>
		return (nil, "known kind of window");
	}
	return (d, nil);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.