aboutsummaryrefslogtreecommitdiff
path: root/src/libplumb/fid.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-06-09 14:04:33 +0000
committerrsc <devnull@localhost>2004-06-09 14:04:33 +0000
commit4f604b1843899782071d3dedbb31c6a2e441213f (patch)
tree7c924f1da412108b505286c50f887e8c0f349fec /src/libplumb/fid.c
parent4192ac1de11674c91bbe390fc8afa187657f9223 (diff)
downloadplan9port-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.c144
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;
+}
+