Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include <sunrpc.h>
6 enum
7 {
8 MaxRead = 17000
9 };
11 typedef struct SunMsgFd SunMsgFd;
12 struct SunMsgFd
13 {
14 SunMsg msg;
15 int fd;
16 };
18 typedef struct Arg Arg;
19 struct Arg
20 {
21 SunSrv *srv;
22 Channel *creply;
23 Channel *csync;
24 int fd;
25 };
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;
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 void
65 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) != 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 }
88 int
89 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;