aboutsummaryrefslogtreecommitdiff
path: root/src/lib9p/ramfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib9p/ramfs.c')
-rw-r--r--src/lib9p/ramfs.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/lib9p/ramfs.c b/src/lib9p/ramfs.c
new file mode 100644
index 00000000..a2f0b3d7
--- /dev/null
+++ b/src/lib9p/ramfs.c
@@ -0,0 +1,163 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.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 *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 's':
+ srvname = EARGF(usage());
+ break;
+ case 'm':
+ mtpt = EARGF(usage());
+ break;
+ default:
+ usage();
+ }ARGEND;
+
+ if(argc)
+ usage();
+
+ if(chatty9p)
+ fprint(2, "ramsrv.nopipe %d srvname %s mtpt %s\n", fs.nopipe, srvname, mtpt);
+ if(srvname == nil && mtpt == nil)
+ sysfatal("you should at least specify a -s or -m option");
+
+ postmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
+ exits(0);
+}