diff options
author | rsc <devnull@localhost> | 2004-06-09 14:04:33 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-06-09 14:04:33 +0000 |
commit | 4f604b1843899782071d3dedbb31c6a2e441213f (patch) | |
tree | 7c924f1da412108b505286c50f887e8c0f349fec /src/libplumb/fid.c | |
parent | 4192ac1de11674c91bbe390fc8afa187657f9223 (diff) | |
download | plan9port-4f604b1843899782071d3dedbb31c6a2e441213f.tar.gz plan9port-4f604b1843899782071d3dedbb31c6a2e441213f.tar.bz2 plan9port-4f604b1843899782071d3dedbb31c6a2e441213f.zip |
change to plumb better
Diffstat (limited to 'src/libplumb/fid.c')
-rw-r--r-- | src/libplumb/fid.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/libplumb/fid.c b/src/libplumb/fid.c new file mode 100644 index 00000000..86093c05 --- /dev/null +++ b/src/libplumb/fid.c @@ -0,0 +1,144 @@ +#include <u.h> +#include <libc.h> +#include <fcall.h> +#include <fs.h> +#include "plumb.h" + +static Fsys *fsplumb; +static int pfd = -1; +static Fid *pfid; + +int +plumbopen(char *name, int omode) +{ + if(fsplumb == nil) + fsplumb = nsmount("plumb", ""); + if(fsplumb == nil) + return -1; + /* + * It's important that when we send something, + * we find out whether it was a valid plumb write. + * (If it isn't, the client might fall back to some + * other mechanism or indicate to the user what happened.) + * We can't use a pipe for this, so we have to use the + * fid interface. But we need to return a fd. + * Return a fd for /dev/null so that we return a unique + * file descriptor. In plumbsend we'll look for pfd + * and use the recorded fid instead. + */ + if((omode&3) == OWRITE){ + if(pfd != -1){ + werrstr("already have plumb send open"); + return -1; + } + pfd = open("/dev/null", OWRITE); + if(pfd < 0) + return -1; + pfid = fsopen(fsplumb, name, omode); + if(pfid == nil){ + close(pfd); + pfd = -1; + return -1; + } + return pfd; + } + + return fsopenfd(fsplumb, name, omode); +} + +Fid* +plumbopenfid(char *name, int mode) +{ + if(fsplumb == nil) + fsplumb = nsmount("plumb", ""); + if(fsplumb == nil) + return nil; + return fsopen(fsplumb, name, mode); +} + +int +plumbsendtofid(Fid *fid, Plumbmsg *m) +{ + char *buf; + int n; + + if(fid == nil){ + werrstr("invalid fid"); + return -1; + } + buf = plumbpack(m, &n); + if(buf == nil) + return -1; + n = fswrite(fid, buf, n); + free(buf); + return n; +} + +int +plumbsend(int fd, Plumbmsg *m) +{ + if(fd == -1){ + werrstr("invalid fd"); + return -1; + } + if(fd != pfd){ + werrstr("fd is not the plumber"); + return -1; + } + return plumbsendtofid(pfid, m); +} + +Plumbmsg* +plumbrecv(int fd) +{ + char *buf; + Plumbmsg *m; + int n, more; + + buf = malloc(8192); + if(buf == nil) + return nil; + n = read(fd, buf, 8192); + m = nil; + if(n > 0){ + m = plumbunpackpartial(buf, n, &more); + if(m==nil && more>0){ + /* we now know how many more bytes to read for complete message */ + buf = realloc(buf, n+more); + if(buf == nil) + return nil; + if(readn(fd, buf+n, more) == more) + m = plumbunpackpartial(buf, n+more, nil); + } + } + free(buf); + return m; +} + +Plumbmsg* +plumbrecvfid(Fid *fid) +{ + char *buf; + Plumbmsg *m; + int n, more; + + buf = malloc(8192); + if(buf == nil) + return nil; + n = fsread(fid, buf, 8192); + m = nil; + if(n > 0){ + m = plumbunpackpartial(buf, n, &more); + if(m==nil && more>0){ + /* we now know how many more bytes to read for complete message */ + buf = realloc(buf, n+more); + if(buf == nil) + return nil; + if(fsreadn(fid, buf+n, more) == more) + m = plumbunpackpartial(buf, n+more, nil); + } + } + free(buf); + return m; +} + |