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