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

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


#include <u.h>
#include <libc.h>

/*
 * create a remote inferno window to run a local plan 9 command.
 * -r option creates a graphical window.
 * interacts with newwinsrv (as in /n/rwin)
 */

void rmtnoteproc(int);
void execp(char **);

char *shcmd[] = {"/bin/rc", "-i", nil};
char *riocmd[] = {"/bin/rio", nil};
char **cmd = shcmd;
void
main(int argc, char **argv)
{
	int ctlfd, fd, n, fd0, fd1, fd2, rio;
	char buf[20], dir[50], path[70], *kind;

	rio = 0;
	ARGBEGIN{
	case 'r':
		rio = 1;
		cmd = riocmd;
		break;
	default:
		fprint(2, "usage: iwin [-r] [cmd [arg...]]\n");
		exits("usage");
	}ARGEND
	if(argc > 0)
		cmd = argv;
		
	fd = open("/mnt/term/n/rwin/new", ORDWR);
	if(fd == -1){
		fprint(2, "iwin: no window creation service available\n");
		exits("error");
	}
	if(fprint(fd, "%s", rio?"rio":"sh") == -1){
		fprint(2, "iwin: cannot create window: %r\n");
		exits("error");
	}
	n = pread(fd, buf, sizeof buf - 1, 0);
	if(n <= 0){
		fprint(2, "iwin: bad window directory\n");
		exits("error");
	}
	buf[n] = 0;
	snprint(dir, sizeof dir, "/mnt/term/n/rwin/%s", buf);
fprint(2, "win directory %s\n", dir);

	if(fork())
		exits(nil);
	rfork(RFNAMEG|RFFDG);
	if(!rio){
		snprint(path, sizeof path, "%s/shctl", dir);
		ctlfd = open(path, ORDWR);
		if(ctlfd == -1)
			fprint(2, "cannot open %s: %r\n", path);
		fprint(ctlfd, "action Interrupt interrupt");
		rmtnoteproc(ctlfd);
	}

	bind(dir, "/dev", MBEFORE);

	close(0);
	close(1);
	close(2);
	fd0 = open("/dev/cons", OREAD|ORCLOSE);
	fd1 = open("/dev/cons", OWRITE);
	fd2 = open("/dev/cons", OWRITE);
	execp(cmd);
	fprint(2, "failed to exec %s: %r\n", cmd[0]);
}

void
execp(char **argv)
{
	char *p;
	char *path;
	p = argv[0];
	if(p[0] == '.' && p[1] == '/' || p[0] == '/')
		exec(p, argv);
	else{
		path = malloc(strlen(p)+6);
		sprint(path, "/bin/%s", p);
		exec(path, argv);
		exec(p, argv);
	}
}

/*
 *  loop reading /mnt/term/dev/note looking for notes.
 *  The child returns to start the shell.
 *
 *  taken verbatim from /sys/src/cmd/cpu.c
 */
void
rmtnoteproc(int fd)
{
	int n, pid, notepid;
	char buf[256];

	/* new proc returns to start shell */
	pid = rfork(RFPROC|RFFDG|RFNOTEG|RFNAMEG|RFMEM);
	switch(pid){
	case -1:
		syslog(0, "cpu", "cpu -R: can't start noteproc: %r");
		return;
	case 0:
		return;
	}

	/* new proc reads notes from other side and posts them to shell */
	switch(notepid = rfork(RFPROC|RFFDG|RFMEM)){
	case -1:
		syslog(0, "cpu", "cpu -R: can't start wait proc: %r");
		_exits(0);
	case 0:
	
		for(;;){
			n = read(fd, buf, sizeof(buf)-1);
			if(n <= 0){
				postnote(PNGROUP, pid, "hangup");
				_exits(0);
			}
			buf[n] = 0;
			postnote(PNGROUP, pid, buf);
		}
		break;
	}

	/* original proc waits for shell proc to die and kills note proc */
	for(;;){
		n = waitpid();
		if(n < 0 || n == pid)
			break;
	}
	postnote(PNPROC, notepid, "kill");
	_exits(0);
}

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.