plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

fd.c (1733B)


      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 }