xref: /plan9/sys/src/cmd/cec/mux.c (revision 60014d6756a98ad10929607ca84a1b7488a16cfc)
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