fd.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 <thread.h>
  12. #include <sunrpc.h>
  13. enum
  14. {
  15. MaxRead = 17000,
  16. };
  17. typedef struct SunMsgFd SunMsgFd;
  18. struct SunMsgFd
  19. {
  20. SunMsg msg;
  21. int fd;
  22. };
  23. typedef struct Arg Arg;
  24. struct Arg
  25. {
  26. SunSrv *srv;
  27. Channel *creply;
  28. Channel *csync;
  29. int fd;
  30. };
  31. static void
  32. sunFdRead(void *v)
  33. {
  34. uint n, tot;
  35. int done;
  36. uint8_t buf[4], *p;
  37. Arg arg = *(Arg*)v;
  38. SunMsgFd *msg;
  39. sendp(arg.csync, 0);
  40. p = nil;
  41. tot = 0;
  42. for(;;){
  43. n = readn(arg.fd, buf, 4);
  44. if(n != 4)
  45. break;
  46. n = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3];
  47. if(arg.srv->chatty) fprint(2, "%.8ux...", n);
  48. done = n&0x80000000;
  49. n &= ~0x80000000;
  50. p = erealloc(p, tot+n);
  51. if(readn(arg.fd, p+tot, n) != n)
  52. break;
  53. tot += n;
  54. if(done){
  55. msg = emalloc(sizeof(SunMsgFd));
  56. msg->msg.data = p;
  57. msg->msg.count = tot;
  58. msg->msg.creply = arg.creply;
  59. sendp(arg.srv->crequest, msg);
  60. p = nil;
  61. tot = 0;
  62. }
  63. }
  64. }
  65. static void
  66. sunFdWrite(void *v)
  67. {
  68. uint8_t buf[4];
  69. uint32_t n;
  70. Arg arg = *(Arg*)v;
  71. SunMsgFd *msg;
  72. sendp(arg.csync, 0);
  73. while((msg = recvp(arg.creply)) != nil){
  74. n = msg->msg.count;
  75. buf[0] = (n>>24)|0x80;
  76. buf[1] = n>>16;
  77. buf[2] = n>>8;
  78. buf[3] = n;
  79. if(write(arg.fd, buf, 4) != 4
  80. || write(arg.fd, msg->msg.data, msg->msg.count) != msg->msg.count)
  81. fprint(2, "sunFdWrite: %r\n");
  82. free(msg->msg.data);
  83. free(msg);
  84. }
  85. }
  86. int
  87. sunSrvFd(SunSrv *srv, int fd)
  88. {
  89. Arg *arg;
  90. arg = emalloc(sizeof(Arg));
  91. arg->fd = fd;
  92. arg->srv = srv;
  93. arg->csync = chancreate(sizeof(void*), 0);
  94. arg->creply = chancreate(sizeof(SunMsg*), 10);
  95. proccreate(sunFdRead, arg, SunStackSize);
  96. proccreate(sunFdWrite, arg, SunStackSize);
  97. recvp(arg->csync);
  98. recvp(arg->csync);
  99. chanfree(arg->csync);
  100. free(arg);
  101. return 0;
  102. }