summaryrefslogtreecommitdiff
path: root/sys/src/cmd/cec/mux.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/cec/mux.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/cec/mux.c')
-rwxr-xr-xsys/src/cmd/cec/mux.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/sys/src/cmd/cec/mux.c b/sys/src/cmd/cec/mux.c
new file mode 100755
index 000000000..66f4fa6df
--- /dev/null
+++ b/sys/src/cmd/cec/mux.c
@@ -0,0 +1,110 @@
+#include <u.h>
+#include <libc.h>
+#include "cec.h"
+
+typedef struct {
+ char type;
+ char pad[3];
+ Pkt p;
+} Muxmsg;
+
+typedef struct {
+ int fd;
+ int type;
+ int pid;
+} Muxproc;
+
+struct Mux {
+ Muxmsg m;
+ Muxproc p[2];
+ int pfd[2];
+ int inuse;
+};
+
+static Mux smux = {
+.inuse = -1,
+};
+
+void
+muxcec(int, int cfd)
+{
+ Muxmsg m;
+ int l;
+
+ m.type = Fcec;
+ while((l = netget(&m.p, sizeof m.p)) > 0)
+ if(write(cfd, &m, l+4) != l+4)
+ break;
+ exits("");
+}
+
+void
+muxkbd(int kfd, int cfd)
+{
+ Muxmsg m;
+
+ m.type = Fkbd;
+ while((m.p.len = read(kfd, m.p.data, sizeof m.p.data)) > 0)
+ if(write(cfd, &m, m.p.len+22) != m.p.len+22)
+ break;
+ m.type = Ffatal;
+ write(cfd, &m, 4);
+ exits("");
+}
+
+int
+muxproc(Mux *m, Muxproc *p, int fd, void (*f)(int, int), int type)
+{
+ memset(p, 0, sizeof p);
+ p->type = -1;
+ switch(p->pid = rfork(RFPROC|RFFDG)){
+ case -1:
+ return -1;
+ case 0:
+ close(m->pfd[0]);
+ f(fd, m->pfd[1]);
+ default:
+ p->fd = fd;
+ p->type = type;
+ return p->pid;
+ }
+}
+
+void
+muxfree(Mux *m)
+{
+ close(m->pfd[0]);
+ close(m->pfd[1]);
+ postnote(PNPROC, m->p[0].pid, "this note goes to 11");
+ postnote(PNPROC, m->p[1].pid, "this note goes to 11");
+ waitpid();
+ waitpid();
+ memset(m, 0, sizeof *m);
+ m->inuse = -1;
+}
+
+Mux*
+mux(int fd[2])
+{
+ Mux *m;
+
+ if(smux.inuse != -1)
+ sysfatal("mux in use");
+ m = &smux;
+ m->inuse = 1;
+ if(pipe(m->pfd) == -1)
+ sysfatal("pipe: %r");
+ muxproc(m, m->p+0, fd[0], muxkbd, Fkbd);
+ muxproc(m, m->p+1, fd[1], muxcec, Fcec);
+ close(m->pfd[1]);
+ return m;
+}
+
+int
+muxread(Mux *m, Pkt *p)
+{
+ if(read(m->pfd[0], &m->m, sizeof m->m) == -1)
+ return -1;
+ memcpy(p, &m->m.p, sizeof *p);
+ return m->m.type;
+}