fd.c 1.7 KB

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