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.
This commit is contained in:
cinap_lenrek 2012-11-06 17:19:41 +01:00
parent 120412a6a2
commit 599dd1c34f
4 changed files with 83 additions and 32 deletions

View file

@ -154,6 +154,12 @@ fn main{
# 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 @@ if(! ~ $#aa 0 && ~ $#bootargs 0 && ~ $#nobootprompt 0){
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

View file

@ -93,6 +93,7 @@ int scanfd;
int ledsfd;
int consfd;
int mctlfd;
int notefd;
int kbdopen;
int consctlopen;
@ -566,6 +567,10 @@ lineproc(void *aux)
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,18 +1290,25 @@ reboot(void)
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;
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 */
@ -1351,6 +1363,8 @@ threadmain(int argc, char** argv)
usage();
}ARGEND
notefd = procopen(getpid(), "notepg", OWRITE);
scanfd = eopen("/dev/scancode", OREAD);
ledsfd = eopen("/dev/leds", OWRITE);
mctlfd = eopen("/dev/mousectl", OWRITE);

View file

@ -7,6 +7,7 @@ char* readenv(char*);
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 @@ main(int argc, char *argv[])
{
char *user;
int fd;
char ctl[128];
closefds();
@ -43,14 +43,12 @@ main(int argc, char *argv[])
}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 @@ pass(int fd)
}
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 @@ void
fexec(void (*execfn)(void))
{
Waitmsg *w;
int pid;
int fd, pid;
switch(pid=fork()){
case 0:
@ -138,11 +140,15 @@ fexec(void (*execfn)(void))
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 @@ fexec(void (*execfn)(void))
free(w);
break;
}
if(fd >= 0)
close(fd);
}
void
@ -267,3 +275,16 @@ closefds(void)
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;
}

View file

@ -197,46 +197,54 @@ main(int argc, char **argv)
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);
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);