diff --git a/xrxs.c b/xrxs.c index 7911c3a..7586466 100644 --- a/xrxs.c +++ b/xrxs.c @@ -22,20 +22,120 @@ char *ccat(char *dst, char c) { int len = slen(dst); dst[len] = c; dst[len + 1] /* clang-format on */ -int i = 0; +static char Ebad[] = "something bad happened"; +static char Enomem[] = "no memory"; + +typedef struct Ramfile Ramfile; +struct Ramfile { + char* data; + int ndata; +}; void fsread(Req* r) { - char numReads[32]; - i++; - sprintf(numReads, "Hello from 9p!\n%d reads\n", i); - readstr(r, numReads); + Ramfile* rf; + vlong offset; + long count; + + rf = r->fid->file->aux; + offset = r->ifcall.offset; + count = r->ifcall.count; + + /*print("read %ld %lld\n", *count, offset); */ + if (offset >= rf->ndata) { + r->ofcall.count = 0; + respond(r, nil); + return; + } + + if (offset + count >= rf->ndata) + count = rf->ndata - offset; + + memmove(r->ofcall.data, rf->data + offset, count); + r->ofcall.count = count; respond(r, nil); } +void fswrite(Req* r) { + void* v; + Ramfile* rf; + vlong offset; + long count; + + rf = r->fid->file->aux; + offset = r->ifcall.offset; + count = r->ifcall.count; + + if (offset + count >= rf->ndata) { + v = realloc(rf->data, offset + count); + if (v == nil) { + respond(r, Enomem); + return; + } + rf->data = v; + rf->ndata = offset + count; + r->fid->file->dir.length = rf->ndata; + } + memmove(rf->data + offset, r->ifcall.data, count); + r->ofcall.count = count; + respond(r, nil); +} + +void fscreate(Req* r) { + Ramfile* rf; + File* f; + + if ( + f = createfile( + r->fid->file, + r->ifcall.name, + nil, + r->ifcall.perm, + nil)) { + rf = emalloc9p(sizeof *rf); + f->aux = rf; + r->fid->file = f; + r->ofcall.qid = f->dir.qid; + respond(r, nil); + return; + } + respond(r, Ebad); +} + +void fsopen(Req* r) { + Ramfile* rf; + + rf = r->fid->file->aux; + + if (rf && (r->ifcall.mode & OTRUNC)) { + rf->ndata = 0; + r->fid->file->dir.length = 0; + } + + respond(r, nil); +} + +void fsdestroyfile(File* f) { + Ramfile* rf; + + /*fprint(2, "clunk\n"); */ + rf = f->aux; + if (rf) { + free(rf->data); + free(rf); + } +} + Srv fs = { + .open = fsopen, .read = fsread, + .write = fswrite, + .create = fscreate, }; +int threadmaybackground(void) { + return 1; +} + void threadmain(int argc, char* argv[]) { Tree* tree; char* mtpt = nil; @@ -60,10 +160,8 @@ void threadmain(int argc, char* argv[]) { /* create a single file called 'hello'. reading it calls fsread() */ - tree = alloctree(nil, nil, DMDIR | 0555, nil); - fs.tree = tree; - fs.foreground = 1; - createfile(tree->root, "hello", nil, 0555, nil); + fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile); + fs.foreground = 1; if (argc >= 3) { if (mtpt != nil && access(mtpt, AEXIST) < 0 && access(mtpt, AEXIST) < 0)