xref: /plan9/sys/src/libsunrpc/fd.c (revision fb7f0c934c48abaed6040d054ef636408c3c522d)
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