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