URI:
       tfid.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tfid.c (2894B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <fcall.h>
            4 #include <9pclient.h>
            5 #include "plumb.h"
            6 
            7 static CFsys *fsplumb;
            8 static int pfd = -1;
            9 static CFid *pfid;
           10 
           11 int
           12 plumbunmount(void)
           13 {
           14         CFsys *fsys;
           15 
           16         if(fsplumb){
           17                 fsys = fsplumb;
           18                 fsplumb = nil;
           19                 fsunmount(fsys);
           20         }
           21         return 0;
           22 }
           23 
           24 int
           25 plumbopen(char *name, int omode)
           26 {
           27         if(fsplumb == nil)
           28                 fsplumb = nsmount("plumb", "");
           29         if(fsplumb == nil)
           30                 return -1;
           31         /*
           32         * It's important that when we send something,
           33         * we find out whether it was a valid plumb write.
           34         * (If it isn't, the client might fall back to some
           35         * other mechanism or indicate to the user what happened.)
           36         * We can't use a pipe for this, so we have to use the
           37         * fid interface.  But we need to return a fd.
           38         * Return a fd for /dev/null so that we return a unique
           39         * file descriptor.  In plumbsend we'll look for pfd
           40         * and use the recorded fid instead.
           41         */
           42         if((omode&3) == OWRITE){
           43                 if(pfd != -1){
           44                         werrstr("already have plumb send open");
           45                         return -1;
           46                 }
           47                 pfd = open("/dev/null", OWRITE);
           48                 if(pfd < 0)
           49                         return -1;
           50                 pfid = fsopen(fsplumb, name, omode);
           51                 if(pfid == nil){
           52                         close(pfd);
           53                         pfd = -1;
           54                         return -1;
           55                 }
           56                 return pfd;
           57         }
           58 
           59         return fsopenfd(fsplumb, name, omode);
           60 }
           61 
           62 CFid*
           63 plumbopenfid(char *name, int mode)
           64 {
           65         if(fsplumb == nil){
           66                 fsplumb = nsmount("plumb", "");
           67                 if(fsplumb == nil){
           68                         werrstr("mount plumb: %r");
           69                         return nil;
           70                 }
           71         }
           72         return fsopen(fsplumb, name, mode);
           73 }
           74 
           75 int
           76 plumbsendtofid(CFid *fid, Plumbmsg *m)
           77 {
           78         char *buf;
           79         int n;
           80 
           81         if(fid == nil){
           82                 werrstr("invalid fid");
           83                 return -1;
           84         }
           85         buf = plumbpack(m, &n);
           86         if(buf == nil)
           87                 return -1;
           88         n = fswrite(fid, buf, n);
           89         free(buf);
           90         return n;
           91 }
           92 
           93 int
           94 plumbsend(int fd, Plumbmsg *m)
           95 {
           96         if(fd == -1){
           97                 werrstr("invalid fd");
           98                 return -1;
           99         }
          100         if(fd != pfd){
          101                 werrstr("fd is not the plumber");
          102                 return -1;
          103         }
          104         return plumbsendtofid(pfid, m);
          105 }
          106 
          107 Plumbmsg*
          108 plumbrecv(int fd)
          109 {
          110         char *buf;
          111         Plumbmsg *m;
          112         int n, more;
          113 
          114         buf = malloc(8192);
          115         if(buf == nil)
          116                 return nil;
          117         n = read(fd, buf, 8192);
          118         m = nil;
          119         if(n > 0){
          120                 m = plumbunpackpartial(buf, n, &more);
          121                 if(m==nil && more>0){
          122                         /* we now know how many more bytes to read for complete message */
          123                         buf = realloc(buf, n+more);
          124                         if(buf == nil)
          125                                 return nil;
          126                         if(readn(fd, buf+n, more) == more)
          127                                 m = plumbunpackpartial(buf, n+more, nil);
          128                 }
          129         }
          130         free(buf);
          131         return m;
          132 }
          133 
          134 Plumbmsg*
          135 plumbrecvfid(CFid *fid)
          136 {
          137         char *buf;
          138         Plumbmsg *m;
          139         int n, more;
          140 
          141         if(fid == nil){
          142                 werrstr("invalid fid");
          143                 return nil;
          144         }
          145         buf = malloc(8192);
          146         if(buf == nil)
          147                 return nil;
          148         n = fsread(fid, buf, 8192);
          149         m = nil;
          150         if(n > 0){
          151                 m = plumbunpackpartial(buf, n, &more);
          152                 if(m==nil && more>0){
          153                         /* we now know how many more bytes to read for complete message */
          154                         buf = realloc(buf, n+more);
          155                         if(buf == nil)
          156                                 return nil;
          157                         if(fsreadn(fid, buf+n, more) == more)
          158                                 m = plumbunpackpartial(buf, n+more, nil);
          159                 }
          160         }
          161         free(buf);
          162         return m;
          163 }