]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libsunrpc/fd.c
libaml: fix gc bug, need to amltake()/amldrop() temporary buffer
[plan9front.git] / sys / src / libsunrpc / fd.c
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 }