ref: 24784c25acafe9837586ef877b6cc7960a880a83
dir: /kbd/kbdbind.c/
#include <u.h>
#include <libc.h>
enum {
NumF = 12
};
static char *funcs[NumF];
void main(int, char**) {
funcs[0] = "Fi";
funcs[1] = "Ru";
funcs[2] = "window";
int in = open("/dev/kbd", OREAD);
if(in < 0)
sysfatal("open failed: %r");
int p[2];
pipe(p);
int fd = create("/srv/kbdbind", OWRITE, 0600);
if(fd < 0)
sysfatal("create failed: %r");
fprint(fd, "%d", p[0]);
close(fd);
close(p[0]);
int out = p[1];
for(;;) {
uchar b[128];
long size = read(in, b, sizeof(b));
if(size < 0)
break;
for(long i = 0; i < size;) {
int isfunc =
size >= 5 &&
(b[i] == 'k' || b[i] == 'c') &&
b[i+1] == 0xef &&
b[i+2] == 0x80 &&
(b[i+3] >= 0x81 && b[i+3] <= (0x81+NumF));
int funcid = isfunc ? b[i+3] - 0x81 : -1;
if(funcid < 0 || funcs[funcid] == nil) {
int k = i;
for(; i < size; i++) {
if(!b[i]) {
i++;
break;
}
}
if(i - k > 0) {
write(out, &b[k], i - k);
}
} else {
int down = b[i] == 'k';
i += 5;
if(!down)
continue;
switch(rfork(RFFDG|RFREND|RFPROC|RFNOWAIT)) {
case 0:
if(execl("/bin/rc", "/bin/rc", funcs[funcid], 0) < 0)
fprint(2, "execl failed: %r");
break;
case -1:
fprint(2, "rfork failed: %r");
break;
}
}
}
}
}