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);
--
⑨