]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cec/mux.c
cwfs: fix listen filedescriptor leaks
[plan9front.git] / sys / src / cmd / cec / mux.c
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 }