mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
108 lines
1.7 KiB
C
108 lines
1.7 KiB
C
|
#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;
|
||
|
}
|