134e04225SDavid du Colombier #include <u.h>
234e04225SDavid du Colombier #include <libc.h>
334e04225SDavid du Colombier #include <thread.h>
434e04225SDavid du Colombier #include <sunrpc.h>
534e04225SDavid du Colombier
634e04225SDavid du Colombier enum
734e04225SDavid du Colombier {
834e04225SDavid du Colombier MaxRead = 17000,
934e04225SDavid du Colombier };
1034e04225SDavid du Colombier
1134e04225SDavid du Colombier typedef struct SunMsgFd SunMsgFd;
1234e04225SDavid du Colombier struct SunMsgFd
1334e04225SDavid du Colombier {
1434e04225SDavid du Colombier SunMsg msg;
1534e04225SDavid du Colombier int fd;
1634e04225SDavid du Colombier };
1734e04225SDavid du Colombier
1834e04225SDavid du Colombier typedef struct Arg Arg;
1934e04225SDavid du Colombier struct Arg
2034e04225SDavid du Colombier {
2134e04225SDavid du Colombier SunSrv *srv;
2234e04225SDavid du Colombier Channel *creply;
2334e04225SDavid du Colombier Channel *csync;
2434e04225SDavid du Colombier int fd;
2534e04225SDavid du Colombier };
2634e04225SDavid du Colombier
2734e04225SDavid du Colombier static void
sunFdRead(void * v)2834e04225SDavid du Colombier sunFdRead(void *v)
2934e04225SDavid du Colombier {
3034e04225SDavid du Colombier uint n, tot;
3134e04225SDavid du Colombier int done;
3234e04225SDavid du Colombier uchar buf[4], *p;
3334e04225SDavid du Colombier Arg arg = *(Arg*)v;
3434e04225SDavid du Colombier SunMsgFd *msg;
3534e04225SDavid du Colombier
3634e04225SDavid du Colombier sendp(arg.csync, 0);
3734e04225SDavid du Colombier
3834e04225SDavid du Colombier p = nil;
3934e04225SDavid du Colombier tot = 0;
4034e04225SDavid du Colombier for(;;){
4134e04225SDavid du Colombier n = readn(arg.fd, buf, 4);
4234e04225SDavid du Colombier if(n != 4)
4334e04225SDavid du Colombier break;
4434e04225SDavid du Colombier n = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3];
4534e04225SDavid du Colombier if(arg.srv->chatty) fprint(2, "%.8ux...", n);
4634e04225SDavid du Colombier done = n&0x80000000;
4734e04225SDavid du Colombier n &= ~0x80000000;
4834e04225SDavid du Colombier p = erealloc(p, tot+n);
4934e04225SDavid du Colombier if(readn(arg.fd, p+tot, n) != n)
5034e04225SDavid du Colombier break;
5134e04225SDavid du Colombier tot += n;
5234e04225SDavid du Colombier if(done){
5334e04225SDavid du Colombier msg = emalloc(sizeof(SunMsgFd));
5434e04225SDavid du Colombier msg->msg.data = p;
5534e04225SDavid du Colombier msg->msg.count = tot;
5634e04225SDavid du Colombier msg->msg.creply = arg.creply;
5734e04225SDavid du Colombier sendp(arg.srv->crequest, msg);
5834e04225SDavid du Colombier p = nil;
5934e04225SDavid du Colombier tot = 0;
6034e04225SDavid du Colombier }
6134e04225SDavid du Colombier }
6234e04225SDavid du Colombier }
6334e04225SDavid du Colombier
6434e04225SDavid du Colombier static void
sunFdWrite(void * v)6534e04225SDavid du Colombier sunFdWrite(void *v)
6634e04225SDavid du Colombier {
6734e04225SDavid du Colombier uchar buf[4];
6834e04225SDavid du Colombier u32int n;
6934e04225SDavid du Colombier Arg arg = *(Arg*)v;
7034e04225SDavid du Colombier SunMsgFd *msg;
7134e04225SDavid du Colombier
7234e04225SDavid du Colombier sendp(arg.csync, 0);
7334e04225SDavid du Colombier
7434e04225SDavid du Colombier while((msg = recvp(arg.creply)) != nil){
7534e04225SDavid du Colombier n = msg->msg.count;
7634e04225SDavid du Colombier buf[0] = (n>>24)|0x80;
7734e04225SDavid du Colombier buf[1] = n>>16;
7834e04225SDavid du Colombier buf[2] = n>>8;
7934e04225SDavid du Colombier buf[3] = n;
8034e04225SDavid du Colombier if(write(arg.fd, buf, 4) != 4
8134e04225SDavid du Colombier || write(arg.fd, msg->msg.data, msg->msg.count) != msg->msg.count)
8234e04225SDavid du Colombier fprint(2, "sunFdWrite: %r\n");
8334e04225SDavid du Colombier free(msg->msg.data);
8434e04225SDavid du Colombier free(msg);
8534e04225SDavid du Colombier }
8634e04225SDavid du Colombier }
8734e04225SDavid du Colombier
8834e04225SDavid du Colombier int
sunSrvFd(SunSrv * srv,int fd)8934e04225SDavid du Colombier sunSrvFd(SunSrv *srv, int fd)
9034e04225SDavid du Colombier {
9134e04225SDavid du Colombier Arg *arg;
9234e04225SDavid du Colombier
9334e04225SDavid du Colombier arg = emalloc(sizeof(Arg));
9434e04225SDavid du Colombier arg->fd = fd;
9534e04225SDavid du Colombier arg->srv = srv;
9634e04225SDavid du Colombier arg->csync = chancreate(sizeof(void*), 0);
9734e04225SDavid du Colombier arg->creply = chancreate(sizeof(SunMsg*), 10);
9834e04225SDavid du Colombier
9934e04225SDavid du Colombier proccreate(sunFdRead, arg, SunStackSize);
10034e04225SDavid du Colombier proccreate(sunFdWrite, arg, SunStackSize);
10134e04225SDavid du Colombier recvp(arg->csync);
10234e04225SDavid du Colombier recvp(arg->csync);
10334e04225SDavid du Colombier
10434e04225SDavid du Colombier chanfree(arg->csync);
10534e04225SDavid du Colombier free(arg);
106*fb7f0c93SDavid du Colombier return 0;
10734e04225SDavid du Colombier }
108