ref: 1bea44dc3654c8bb7ab47ebeb5c975734a6aa3f4
dir: /pipekbd.c/
#include <u.h> #include <libc.h> #include <bio.h> void main(int argc, char *argv[]) { int n, kinfd, koutfd, fd[2]; char buf[128]; int kbd; kbd = 1; if((kinfd = open("/dev/kbd", OREAD)) < 0){ kbd = 0; if((kinfd = open("/dev/cons", OREAD)) < 0) sysfatal("open kbd: %r"); } if(bind("#|", "/n/temp", MREPL) < 0) sysfatal("bind /n/temp: %r"); if((koutfd = open("/n/temp/data1", OWRITE)) < 0) sysfatal("open kbd pipe: %r"); if(bind("/n/temp/data", kbd? "/dev/kbd": "/dev/cons", MREPL) < 0) sysfatal("bind kbd pipe: %r"); unmount(nil, "/n/temp"); if(fork()) exits(nil); /* parent exits */ if(!kbd){ dup(kinfd, 0); dup(koutfd, 1); Run: close(kinfd); close(koutfd); if(argv[1][0] != '/' || strncmp(argv[1], "./", 2) != 0 || strncmp(argv[1], "../", 3) != 0) argv[1] = smprint("/bin/%s", argv[1]); exec(argv[1], argv+1); sysfatal("exec: %r"); } if(pipe(fd) < 0) sysfatal("pipe: %r"); if(fork()){ dup(fd[0], 0); dup(fd[0], 1); close(fd[0]); close(fd[1]); goto Run; } close(fd[0]); if(fork()){ Biobuf b; long r; Binit(&b, fd[1], OREAD); while((r = Bgetrune(&b)) >= 0){ n = snprint(buf, sizeof(buf), "c%C", (Rune)r)+1; write(koutfd, buf, n); /* pass on result */ } } else { while((n = read(kinfd, buf, sizeof(buf))) > 0){ buf[n-1] = 0; if(n < 2 || buf[0] != 'c') write(koutfd, buf, n); /* pass on */ else write(fd[1], buf+1, n-2); /* to translator */ } } exits(nil); }