Blob
1 #include <u.h>2 #include <libc.h>3 #include <thread.h>4 #include <sunrpc.h>6 enum7 {8 MaxRead = 17000,9 };11 typedef struct SunMsgFd SunMsgFd;12 struct SunMsgFd13 {14 SunMsg msg;15 int fd;16 };18 typedef struct Arg Arg;19 struct Arg20 {21 SunSrv *srv;22 Channel *creply;23 Channel *csync;24 int fd;25 };27 static void28 sunfdread(void *v)29 {30 uint n, tot;31 int done;32 uchar buf[4], *p;33 Arg arg = *(Arg*)v;34 SunMsgFd *msg;36 sendp(arg.csync, 0);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 }64 static void65 sunfdwrite(void *v)66 {67 uchar buf[4];68 u32int n;69 Arg arg = *(Arg*)v;70 SunMsgFd *msg;72 sendp(arg.csync, 0);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) != 481 || 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 }88 int89 sunsrvfd(SunSrv *srv, int fd)90 {91 Arg *arg;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);99 proccreate(sunfdread, arg, SunStackSize);100 proccreate(sunfdwrite, arg, SunStackSize);101 recvp(arg->csync);102 recvp(arg->csync);104 chanfree(arg->csync);105 free(arg);106 return 0;107 }