git: 9front

Download patch

ref: 359960d22dd75c09fa6ea291aa0a351f3de78ce9
parent: 240218966ed3a75242cd76b5834004894bf80de5
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Tue Nov 6 12:19:41 EST 2012

make interrupt key (Del) just work in the console

these changes make the interrupt key available in the
console (before rio is started).

kbdfs: will now send a "interrupt" note to its invoking
process group in cooked mode.

bootrc: is now prepared to handle interrupts, mainly to
not accidently spawn a new bootargs prompt.

init: forwards the interrupt to the cpurc/termrc pgrp.

vncs: shields itself from kbdfs notegroup so interrrupt
wont kill the whole vnc session.

--- a/sys/src/9/boot/bootrc
+++ b/sys/src/9/boot/bootrc
@@ -154,6 +154,12 @@
 
 # keyboard and serial console
 if(test -x /bin/aux/kbdfs){
+	# make new pgrp different from 1 so kbdfs can open notepg
+	rfork ns
+
+	# ignore interrupts
+	fn sigint {status=interrupted}
+
 	a=$console(1)
 	if(! ~ $#a 0)
 		a=/dev/eia^$a
@@ -209,8 +215,10 @@
 while(){
 	@{main}
 
+	# subshell doesnt wait on interrupts
+	while(~ $status interrupted){wait}
+
 	# cleanup so it can be restarted
 	nobootprompt=()
-	user=()
 	rm -f /srv/^(cfs boot slashn cs dns)
 } </dev/cons
--- a/sys/src/cmd/aux/kbdfs/kbdfs.c
+++ b/sys/src/cmd/aux/kbdfs/kbdfs.c
@@ -93,6 +93,7 @@
 int ledsfd;
 int consfd;
 int mctlfd;
+int notefd;
 
 int kbdopen;
 int consctlopen;
@@ -566,6 +567,10 @@
 			case '\0':	/* flush */
 				nr = 0;
 				continue;
+			case Kdel:
+				if(notefd >= 0)
+					write(notefd, "interrupt", 9);
+				continue;
 			case Kbs:	/* ^H: erase character */
 			case Knack:	/* ^U: erase line */
 			case Ketb:	/* ^W: erase word */
@@ -1285,10 +1290,18 @@
 	close(fd);
 }
 
+int
+procopen(int pid, char *name, int mode)
+{
+	char buf[128];
+
+	snprint(buf, sizeof(buf), "/proc/%d/%s", pid, name);
+	return eopen(buf, mode);
+}
+
 void
 elevate(void)
 {
-	char buf[128];
 	Dir *d, nd;
 	int fd;
 
@@ -1295,8 +1308,7 @@
 	if(debug)
 		return;
 
-	snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid());
-	if((fd = eopen(buf, OWRITE)) < 0)
+	if((fd = procopen(getpid(), "ctl", OWRITE)) < 0)
 		return;
 
 	/* get higher than normal priority */
@@ -1350,6 +1362,8 @@
 	default:
 		usage();
 	}ARGEND
+
+	notefd = procopen(getpid(), "notepg", OWRITE);
 
 	scanfd = eopen("/dev/scancode", OREAD);
 	ledsfd = eopen("/dev/leds", OWRITE);
--- a/sys/src/cmd/init.c
+++ b/sys/src/cmd/init.c
@@ -7,6 +7,7 @@
 void	setenv(char*, char*);
 void	cpenv(char*, char*);
 void	closefds(void);
+int	procopen(int, char*, int);
 void	fexec(void(*)(void));
 void	rcexec(void);
 void	cpustart(void);
@@ -24,7 +25,6 @@
 {
 	char *user;
 	int fd;
-	char ctl[128];
 
 	closefds();
 
@@ -43,14 +43,12 @@
 	}ARGEND
 	cmd = *argv;
 
-	snprint(ctl, sizeof(ctl), "#p/%d/ctl", getpid());
-	fd = open(ctl, OWRITE);
-	if(fd < 0)
-		print("init: warning: can't open %s: %r\n", ctl);
-	else
+	fd = procopen(getpid(), "ctl", OWRITE);
+	if(fd >= 0){
 		if(write(fd, "pri 10", 6) != 6)
 			print("init: warning: can't set priority: %r\n");
-	close(fd);
+		close(fd);
+	}
 
 	cpu = readenv("#e/cputype");
 	setenv("#e/objtype", cpu);
@@ -113,12 +111,16 @@
 }
 
 static int gotnote;
+static int interrupted;
 
 void
 pinhead(void*, char *msg)
 {
 	gotnote = 1;
-	fprint(2, "init got note '%s'\n", msg);
+	if(strcmp(msg, "interrupt") == 0)
+		interrupted = 1;
+	else
+		fprint(2, "init got note '%s'\n", msg);
 	noted(NCONT);
 }
 
@@ -126,7 +128,7 @@
 fexec(void (*execfn)(void))
 {
 	Waitmsg *w;
-	int pid;
+	int fd, pid;
 
 	switch(pid=fork()){
 	case 0:
@@ -138,11 +140,15 @@
 		print("init: fork error: %r\n");
 		exits("fork");
 	default:
+		fd = procopen(pid, "notepg", OWRITE);
 	casedefault:
 		notify(pinhead);
+		interrupted = 0;
 		gotnote = 0;
 		w = wait();
 		if(w == nil){
+			if(interrupted && fd >= 0)
+				write(fd, "interrupt", 9);
 			if(gotnote)
 				goto casedefault;
 			print("init: wait error: %r\n");
@@ -164,6 +170,8 @@
 		free(w);
 		break;
 	}
+	if(fd >= 0)
+		close(fd);
 }
 
 void
@@ -266,4 +274,17 @@
 
 	for(i = 3; i < 30; i++)
 		close(i);
+}
+
+int
+procopen(int pid, char *name, int mode)
+{
+	char buf[128];
+	int fd;
+
+	snprint(buf, sizeof(buf), "#p/%d/%s", pid, name);
+	fd = open(buf, mode);
+	if(fd < 0)
+		print("init: warning: can't open %s: %r\n", name);
+	return fd;
 }
--- a/sys/src/cmd/vnc/vncs.c
+++ b/sys/src/cmd/vnc/vncs.c
@@ -197,33 +197,38 @@
 		sysfatal("mounter: %r");
 	close(fd);
 
-	/* start and mount kbdfs */
-	switch(cmdpid = rfork(RFPROC|RFMEM|RFFDG|RFREND)){
+	cmdpid = rfork(RFPROC|RFMEM|RFFDG|RFNOTEG);
+	switch(cmdpid){
 	case -1:
 		sysfatal("rfork: %r");
 		break;
 	case 0:
 		close(exportfd);
+
 		close(1);
 		open("/dev/cons", OWRITE);
 		close(2);
 		open("/dev/cons", OWRITE);
-		exec(kbdfs[0], kbdfs);
-		_exits("kbdfs");
-	}
-	if(waitpid() != cmdpid)
-		sysfatal("%s: %r", kbdfs[0]);
-	if((kbdin = open("/dev/kbdin", OWRITE)) < 0)
-		sysfatal("open /dev/kbdin: %r");
 
-	/* run the command */
-	switch(cmdpid = rfork(RFPROC|RFMEM|RFFDG|RFNAMEG|RFREND|RFNOTEG)){
-	case -1:
-		sysfatal("rfork: %r");
-		break;
-	case 0:
-		close(exportfd);
-		close(kbdin);
+		/* start and mount kbdfs */
+		cmdpid = rfork(RFPROC|RFMEM|RFFDG|RFREND);
+		switch(cmdpid){
+		case -1:
+			sysfatal("rfork: %r");
+			break;
+		case 0:
+			exec(kbdfs[0], kbdfs);
+			fprint(2, "exec %s: %r\n", kbdfs[0]);
+			_exits("kbdfs");
+		}
+		if(waitpid() != cmdpid){
+			rendezvous(&kbdin, nil);
+			sysfatal("%s: %r", kbdfs[0]);
+		}
+		rendezvous(&kbdin, nil);
+
+		rfork(RFNAMEG|RFREND);
+
 		close(0);
 		open("/dev/cons", OREAD);
 		close(1);
@@ -230,13 +235,16 @@
 		open("/dev/cons", OWRITE);
 		close(2);
 		open("/dev/cons", OWRITE);
+
 		exec(argv[0], argv);
 		fprint(2, "exec %s: %r\n", argv[0]);
 		_exits(nil);
 	}
 
-	unmount(nil, "/dev");
-	bind("#c", "/dev", MREPL);
+	/* wait for kbdfs to get mounted */
+	rendezvous(&kbdin, nil);
+	if((kbdin = open("/dev/kbdin", OWRITE)) < 0)
+		sysfatal("open /dev/kbdin: %r");
 
 	/* run the service */
 	srvfd = vncannounce(net, display, adir, baseport);
--