mux.c 1.6 KB

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