Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}