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