ref: e391b7ec8c0dc746a70725f3fc598def0419d1e6
dir: /sys/src/lib9p/ramfs.c/
#include <u.h> #include <libc.h> #include <fcall.h> #include <thread.h> #include <9p.h> 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) { 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->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, r->fid->uid, r->ifcall.perm, nil)){ rf = emalloc9p(sizeof *rf); f->aux = rf; r->fid->file = f; r->ofcall.qid = f->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->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, }; void usage(void) { fprint(2, "usage: ramfs [-D] [-s srvname] [-m mtpt]\n"); exits("usage"); } void main(int argc, char **argv) { char *addr = nil; char *srvname = nil; char *mtpt = nil; Qid q; fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile); q = fs.tree->root->qid; ARGBEGIN{ case 'D': chatty9p++; break; case 'a': addr = EARGF(usage()); break; case 's': srvname = EARGF(usage()); break; case 'm': mtpt = EARGF(usage()); break; default: usage(); }ARGEND; if(argc) usage(); if(chatty9p) fprint(2, "srvname %s mtpt %s\n", srvname, mtpt); if(addr == nil && srvname == nil && mtpt == nil) sysfatal("must specify -a, -s, or -m option"); if(addr) listensrv(&fs, addr); if(srvname || mtpt) postmountsrv(&fs, srvname, mtpt, MREPL|MCREATE); exits(0); }