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