1 #include <u.h> 2 #include <libc.h> 3 #include "cec.h" 4 5 typedef struct { 6 char type; 7 char pad[3]; 8 Pkt p; 9 } Muxmsg; 10 11 typedef struct { 12 int fd; 13 int type; 14 int pid; 15 } Muxproc; 16 17 struct Mux { 18 Muxmsg m; 19 Muxproc p[2]; 20 int pfd[2]; 21 int inuse; 22 }; 23 24 static Mux smux = { 25 .inuse = -1, 26 }; 27 28 void 29 muxcec(int, int cfd) 30 { 31 Muxmsg m; 32 int l; 33 34 m.type = Fcec; 35 while((l = netget(&m.p, sizeof m.p)) > 0) 36 if(write(cfd, &m, l+4) != l+4) 37 break; 38 exits(""); 39 } 40 41 void 42 muxkbd(int kfd, int cfd) 43 { 44 Muxmsg m; 45 46 m.type = Fkbd; 47 while((m.p.len = read(kfd, m.p.data, sizeof m.p.data)) > 0) 48 if(write(cfd, &m, m.p.len+22) != m.p.len+22) 49 break; 50 m.type = Ffatal; 51 write(cfd, &m, 4); 52 exits(""); 53 } 54 55 int 56 muxproc(Mux *m, Muxproc *p, int fd, void (*f)(int, int), int type) 57 { 58 memset(p, 0, sizeof p); 59 p->type = -1; 60 switch(p->pid = rfork(RFPROC|RFFDG)){ 61 case -1: 62 return -1; 63 case 0: 64 close(m->pfd[0]); 65 f(fd, m->pfd[1]); 66 default: 67 p->fd = fd; 68 p->type = type; 69 return p->pid; 70 } 71 } 72 73 void 74 muxfree(Mux *m) 75 { 76 close(m->pfd[0]); 77 close(m->pfd[1]); 78 postnote(PNPROC, m->p[0].pid, "this note goes to 11"); 79 postnote(PNPROC, m->p[1].pid, "this note goes to 11"); 80 waitpid(); 81 waitpid(); 82 memset(m, 0, sizeof *m); 83 m->inuse = -1; 84 } 85 86 Mux* 87 mux(int fd[2]) 88 { 89 Mux *m; 90 91 if(smux.inuse != -1) 92 sysfatal("mux in use"); 93 m = &smux; 94 m->inuse = 1; 95 if(pipe(m->pfd) == -1) 96 sysfatal("pipe: %r"); 97 muxproc(m, m->p+0, fd[0], muxkbd, Fkbd); 98 muxproc(m, m->p+1, fd[1], muxcec, Fcec); 99 close(m->pfd[1]); 100 return m; 101 } 102 103 int 104 muxread(Mux *m, Pkt *p) 105 { 106 if(read(m->pfd[0], &m->m, sizeof m->m) == -1) 107 return -1; 108 memcpy(p, &m->m.p, sizeof *p); 109 return m->m.type; 110 } 111