summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorMatthew Veety <mveety@mveety.com>2016-02-09 16:24:41 -0500
committerMatthew Veety <mveety@mveety.com>2016-02-09 16:24:41 -0500
commita54782d69b31f3eaeb77a8087016065790c200bb (patch)
tree5f2b06b172f5b58e39321e5d762a162a205cd178 /sys/src
parent9c3de0c87a00e09e8a51d7f6de461a0221c6409b (diff)
Imported ngfs libgio. This is a library to create virtual file descriptors, similar to common lisp grey-streams or golang's io.Reader/io.Writer. Now 95% bug-free.
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/libgio/fd.c59
-rw-r--r--sys/src/libgio/mkfile19
-rw-r--r--sys/src/libgio/openclose.c82
-rw-r--r--sys/src/libgio/readp.c45
-rw-r--r--sys/src/libgio/test.c65
-rw-r--r--sys/src/libgio/writep.c21
6 files changed, 291 insertions, 0 deletions
diff --git a/sys/src/libgio/fd.c b/sys/src/libgio/fd.c
new file mode 100644
index 000000000..b83db6ce0
--- /dev/null
+++ b/sys/src/libgio/fd.c
@@ -0,0 +1,59 @@
+#include <u.h>
+#include <libc.h>
+#include <gio.h>
+
+int fdopen(ReadWriter*);
+int fdclose(ReadWriter*);
+long fdread(ReadWriter*, void*, long, vlong);
+long fdwrite(ReadWriter*, void*, long, vlong);
+
+ReadWriter fdrdwr = {
+ .open = fdopen,
+ .close = fdclose,
+ .pread = fdread,
+ .pwrite = fdwrite,
+};
+
+int
+fdopen(ReadWriter *rd)
+{
+ int *afd = (int*)rd->aux;
+
+ rd->offset = 0;
+ rd->length = (u64int) seek(*afd, 0, 2);
+ seek(*afd, 0, 0);
+ return 0;
+}
+
+int
+fdclose(ReadWriter *rd)
+{
+ void *x = rd->aux;
+ free(x);
+ return 0;
+}
+
+long
+fdread(ReadWriter *rd, void *bf, long len, vlong offset)
+{
+ int *afd = (int*)rd->aux;
+
+ return pread(*afd, bf, len, offset);
+}
+
+long
+fdwrite(ReadWriter *rd, void *bf, long len, vlong offset)
+{
+ int *afd = (int*)rd->aux;
+
+ return pwrite(*afd, bf, len, offset);
+}
+
+int
+fd2gio(int fd)
+{
+ void *x = malloc(sizeof(int));
+ memcpy(x, &fd, sizeof(int));
+ return gopen(&fdrdwr, x);
+}
+
diff --git a/sys/src/libgio/mkfile b/sys/src/libgio/mkfile
new file mode 100644
index 000000000..91d0daf67
--- /dev/null
+++ b/sys/src/libgio/mkfile
@@ -0,0 +1,19 @@
+</$objtype/mkfile
+
+LIB=/$objtype/lib/libgio.a
+OFILES=\
+ fd.$O \
+ openclose.$O \
+ readp.$O \
+ writep.$O \
+
+HFILES=\
+ /sys/include/gio.h\
+
+UPDATE=\
+ mkfile\
+ $HFILES\
+ ${OFILES:%.$O=%.c}\
+ ${LIB:/$objtype/%=/386/%}\
+
+</sys/src/cmd/mksyslib
diff --git a/sys/src/libgio/openclose.c b/sys/src/libgio/openclose.c
new file mode 100644
index 000000000..65f75c213
--- /dev/null
+++ b/sys/src/libgio/openclose.c
@@ -0,0 +1,82 @@
+#include <u.h>
+#include <libc.h>
+#include <gio.h>
+
+RWLock giolock;
+ReadWriter *gio_filedes[256];
+uchar gio_filedes_st[256];
+
+int
+getnext(void)
+{
+ int i;
+ for(i = 0; i < 256; i++)
+ if(gio_filedes_st[i] == 0)
+ break;
+ if(i == 256)
+ return -1;
+ return i;
+}
+
+ReadWriter*
+getrdstruct(int fd)
+{
+ rlock(&giolock);
+ ReadWriter *rval;
+ if(gio_filedes_st[fd] != 1)
+ rval = nil;
+ rval = gio_filedes[fd];
+ runlock(&giolock);
+ return rval;
+}
+
+int
+gopen(ReadWriter* rd, void *aux)
+{
+ int pfd;
+ ReadWriter *buf;
+
+ wlock(&giolock);
+ if(pfd == -1){
+ wunlock(&giolock);
+ return -1;
+ }
+ buf = malloc(sizeof(ReadWriter));
+ if(buf == nil)
+ exits("bad malloc");
+ memcpy(buf, rd, sizeof(ReadWriter));
+ buf->aux = aux;
+ buf->offset = 0;
+ if(buf->open != nil){
+ if((buf->open(buf)) != 0){
+ buf->close(buf);
+ free(buf);
+ wunlock(&giolock);
+ return -1;
+ }
+ }
+ gio_filedes[pfd] = buf;
+ gio_filedes_st[pfd] = 1;
+ wunlock(&giolock);
+ return pfd;
+}
+
+int
+gclose(int fd)
+{
+ ReadWriter *bf;
+ int rval = 0;
+
+ if(gio_filedes_st[fd] == 0)
+ return -1;
+ wlock(&giolock);
+ bf = gio_filedes[fd];
+ if(bf->close != nil)
+ rval = bf->close(bf);
+ free(bf);
+ gio_filedes_st[fd] = 0;
+ gio_filedes[fd] = nil;
+ wunlock(&giolock);
+ return rval;
+}
+
diff --git a/sys/src/libgio/readp.c b/sys/src/libgio/readp.c
new file mode 100644
index 000000000..13ee405ba
--- /dev/null
+++ b/sys/src/libgio/readp.c
@@ -0,0 +1,45 @@
+#include <u.h>
+#include <libc.h>
+#include <gio.h>
+
+long
+gread(int fd, void *bf, long len, vlong offset)
+{
+ ReadWriter *rd;
+ long rval = 0;
+
+ rd = getrdstruct(fd);
+ if(rd == nil)
+ return -1;
+ if(rd->pread == nil)
+ return -2;
+ rlock(rd);
+ rval = rd->pread(rd, bf, offset, len);
+ runlock(rd);
+ return rval;
+}
+
+vlong
+gseek(int fd, vlong offset, int type)
+{
+ ReadWriter *rd;
+
+ rd = getrdstruct(fd);
+ if(rd == nil)
+ return -1;
+ wlock(rd);
+ switch(type){
+ case 0:
+ rd->offset = (u64int)offset;
+ break;
+ case 1:
+ rd->offset = rd->offset + (u64int)offset;
+ break;
+ case 2:
+ rd->offset = rd->length + (u64int)offset;
+ break;
+ }
+ wunlock(rd);
+ return rd->offset;
+}
+
diff --git a/sys/src/libgio/test.c b/sys/src/libgio/test.c
new file mode 100644
index 000000000..8e3cb008f
--- /dev/null
+++ b/sys/src/libgio/test.c
@@ -0,0 +1,65 @@
+#include <u.h>
+#include <libc.h>
+#include <gio.h>
+
+int topen(ReadWriter*);
+int tclose(ReadWriter*);
+long tread(ReadWriter*, void*, long, vlong);
+long twrite(ReadWriter*, void*, long, vlong);
+
+ReadWriter tester = {
+ .open = topen,
+ .close = tclose,
+ .pread = tread,
+ .pwrite = twrite,
+};
+
+void
+main(int argc, char *argv[])
+{
+ int gfd = gopen(&tester, nil);
+ if(gfd < 0){
+ print("gio_test: failed to open gio fd\n");
+ exits("failure");
+ }
+ char *test1 = "Hello World!\n";
+ char test2[256];
+
+ gread(gfd, &test2, 256, 23);
+ gwrite(gfd, test1, sizeof(test1), 8);
+ print("gio_test: %s\n", test2);
+ gclose(gfd);
+ print("gio_test: passed\n");
+ exits(nil);
+}
+
+int
+topen(ReadWriter *rd)
+{
+ print("gio_test: topen: file opened!\n");
+ return 0;
+}
+
+int
+tclose(ReadWriter *rd)
+{
+ print("gio_test: tclose: file closed!\n");
+ return 0;
+}
+
+long
+tread(ReadWriter *rd, void *bf, long len, vlong offset)
+{
+ char *test = "this is a read string!";
+ memcpy(bf, test, strlen(test)+1);
+ print("gio_test: tread: len = %ud, offset = %ud\n", len, offset);
+ return len;
+}
+
+long
+twrite(ReadWriter *rd, void *bf, long len, vlong offset)
+{
+ print("gio_test: twrite: written string: %s\n", bf);
+ print("gio_test: twrite: len = %ud, offset = %ud\n", len, offset);
+ return len;
+}
diff --git a/sys/src/libgio/writep.c b/sys/src/libgio/writep.c
new file mode 100644
index 000000000..0cfeb9530
--- /dev/null
+++ b/sys/src/libgio/writep.c
@@ -0,0 +1,21 @@
+#include <u.h>
+#include <libc.h>
+#include <gio.h>
+
+long
+gwrite(int fd, void *buf, long len, vlong offset)
+{
+ ReadWriter *rd;
+ long rval;
+
+ rd = getrdstruct(fd);
+ if(rd == nil)
+ return -1;
+ if(rd->pwrite == nil)
+ return -2;
+ wlock(rd);
+ rval = rd->pwrite(rd, buf, len, offset);
+ wunlock(rd);
+ return rval;
+}
+