tfd.c - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tfd.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 }