summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-11-06 17:19:41 +0100
committercinap_lenrek <cinap_lenrek@gmx.de>2012-11-06 17:19:41 +0100
commit599dd1c34f1d4e62ee29b2de42eaba7143590347 (patch)
treea7cc4f9983f42263a0b6b02ebcdb3268c60dce1e /sys/src
parent120412a6a2bddf3ae01f4e10bb4173021e802a84 (diff)
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.
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/9/boot/bootrc10
-rw-r--r--sys/src/cmd/aux/kbdfs/kbdfs.c20
-rw-r--r--sys/src/cmd/init.c39
-rw-r--r--sys/src/cmd/vnc/vncs.c46
4 files changed, 83 insertions, 32 deletions
diff --git a/sys/src/9/boot/bootrc b/sys/src/9/boot/bootrc
index 3057df5cb..d6c1aa512 100644
--- a/sys/src/9/boot/bootrc
+++ b/sys/src/9/boot/bootrc
@@ -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
diff --git a/sys/src/cmd/aux/kbdfs/kbdfs.c b/sys/src/cmd/aux/kbdfs/kbdfs.c
index e65cfa0c5..5cc423988 100644
--- a/sys/src/cmd/aux/kbdfs/kbdfs.c
+++ b/sys/src/cmd/aux/kbdfs/kbdfs.c
@@ -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);
diff --git a/sys/src/cmd/init.c b/sys/src/cmd/init.c
index c6c5163fd..d95665279 100644
--- a/sys/src/cmd/init.c
+++ b/sys/src/cmd/init.c
@@ -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;
+}
diff --git a/sys/src/cmd/vnc/vncs.c b/sys/src/cmd/vnc/vncs.c
index 9e983dcc0..ee36d0c7b 100644
--- a/sys/src/cmd/vnc/vncs.c
+++ b/sys/src/cmd/vnc/vncs.c
@@ -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);