mux.c 1.6 KB

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