mux.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include "cec.h"
  12. typedef struct {
  13. char type;
  14. char pad[3];
  15. Pkt p;
  16. } Muxmsg;
  17. typedef struct {
  18. int fd;
  19. int type;
  20. int pid;
  21. } Muxproc;
  22. struct Mux {
  23. Muxmsg m;
  24. Muxproc p[2];
  25. int pfd[2];
  26. int inuse;
  27. };
  28. static Mux smux = {
  29. .inuse = -1,
  30. };
  31. void
  32. muxcec(int, int cfd)
  33. {
  34. Muxmsg m;
  35. int l;
  36. m.type = Fcec;
  37. while((l = netget(&m.p, sizeof m.p)) > 0)
  38. if(write(cfd, &m, l+4) != l+4)
  39. break;
  40. exits("");
  41. }
  42. void
  43. muxkbd(int kfd, int cfd)
  44. {
  45. Muxmsg m;
  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. 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. void
  72. muxfree(Mux *m)
  73. {
  74. close(m->pfd[0]);
  75. close(m->pfd[1]);
  76. postnote(PNPROC, m->p[0].pid, "this note goes to 11");
  77. postnote(PNPROC, m->p[1].pid, "this note goes to 11");
  78. waitpid();
  79. waitpid();
  80. memset(m, 0, sizeof *m);
  81. m->inuse = -1;
  82. }
  83. Mux*
  84. mux(int fd[2])
  85. {
  86. Mux *m;
  87. if(smux.inuse != -1)
  88. sysfatal("mux in use");
  89. m = &smux;
  90. m->inuse = 1;
  91. if(pipe(m->pfd) == -1)
  92. sysfatal("pipe: %r");
  93. muxproc(m, m->p+0, fd[0], muxkbd, Fkbd);
  94. muxproc(m, m->p+1, fd[1], muxcec, Fcec);
  95. close(m->pfd[1]);
  96. return m;
  97. }
  98. int
  99. muxread(Mux *m, Pkt *p)
  100. {
  101. if(read(m->pfd[0], &m->m, sizeof m->m) == -1)
  102. return -1;
  103. memcpy(p, &m->m.p, sizeof *p);
  104. return m->m.type;
  105. }