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:
parent
120412a6a2
commit
599dd1c34f
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue