diff options
author | Matthew Veety <mveety@mveety.com> | 2016-02-09 16:24:41 -0500 |
---|---|---|
committer | Matthew Veety <mveety@mveety.com> | 2016-02-09 16:24:41 -0500 |
commit | a54782d69b31f3eaeb77a8087016065790c200bb (patch) | |
tree | 5f2b06b172f5b58e39321e5d762a162a205cd178 /sys/src | |
parent | 9c3de0c87a00e09e8a51d7f6de461a0221c6409b (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.c | 59 | ||||
-rw-r--r-- | sys/src/libgio/mkfile | 19 | ||||
-rw-r--r-- | sys/src/libgio/openclose.c | 82 | ||||
-rw-r--r-- | sys/src/libgio/readp.c | 45 | ||||
-rw-r--r-- | sys/src/libgio/test.c | 65 | ||||
-rw-r--r-- | sys/src/libgio/writep.c | 21 |
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; +} + |