diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/cec/mux.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/cec/mux.c')
-rwxr-xr-x | sys/src/cmd/cec/mux.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/sys/src/cmd/cec/mux.c b/sys/src/cmd/cec/mux.c new file mode 100755 index 000000000..66f4fa6df --- /dev/null +++ b/sys/src/cmd/cec/mux.c @@ -0,0 +1,110 @@ +#include <u.h> +#include <libc.h> +#include "cec.h" + +typedef struct { + char type; + char pad[3]; + Pkt p; +} Muxmsg; + +typedef struct { + int fd; + int type; + int pid; +} Muxproc; + +struct Mux { + Muxmsg m; + Muxproc p[2]; + int pfd[2]; + int inuse; +}; + +static Mux smux = { +.inuse = -1, +}; + +void +muxcec(int, int cfd) +{ + Muxmsg m; + int l; + + m.type = Fcec; + while((l = netget(&m.p, sizeof m.p)) > 0) + if(write(cfd, &m, l+4) != l+4) + break; + exits(""); +} + +void +muxkbd(int kfd, int cfd) +{ + Muxmsg m; + + m.type = Fkbd; + while((m.p.len = read(kfd, m.p.data, sizeof m.p.data)) > 0) + if(write(cfd, &m, m.p.len+22) != m.p.len+22) + break; + m.type = Ffatal; + write(cfd, &m, 4); + exits(""); +} + +int +muxproc(Mux *m, Muxproc *p, int fd, void (*f)(int, int), int type) +{ + memset(p, 0, sizeof p); + p->type = -1; + switch(p->pid = rfork(RFPROC|RFFDG)){ + case -1: + return -1; + case 0: + close(m->pfd[0]); + f(fd, m->pfd[1]); + default: + p->fd = fd; + p->type = type; + return p->pid; + } +} + +void +muxfree(Mux *m) +{ + close(m->pfd[0]); + close(m->pfd[1]); + postnote(PNPROC, m->p[0].pid, "this note goes to 11"); + postnote(PNPROC, m->p[1].pid, "this note goes to 11"); + waitpid(); + waitpid(); + memset(m, 0, sizeof *m); + m->inuse = -1; +} + +Mux* +mux(int fd[2]) +{ + Mux *m; + + if(smux.inuse != -1) + sysfatal("mux in use"); + m = &smux; + m->inuse = 1; + if(pipe(m->pfd) == -1) + sysfatal("pipe: %r"); + muxproc(m, m->p+0, fd[0], muxkbd, Fkbd); + muxproc(m, m->p+1, fd[1], muxcec, Fcec); + close(m->pfd[1]); + return m; +} + +int +muxread(Mux *m, Pkt *p) +{ + if(read(m->pfd[0], &m->m, sizeof m->m) == -1) + return -1; + memcpy(p, &m->m.p, sizeof *p); + return m->m.type; +} |