Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <fcall.h>
5 #include <thread.h>
6 #include <9p.h>
8 static char Ebad[] = "something bad happened";
9 static char Enomem[] = "no memory";
11 typedef struct Ramfile Ramfile;
12 struct Ramfile {
13 char *data;
14 int ndata;
15 };
17 void
18 fsread(Req *r)
19 {
20 Ramfile *rf;
21 vlong offset;
22 long count;
24 rf = r->fid->file->aux;
25 offset = r->ifcall.offset;
26 count = r->ifcall.count;
28 //print("read %ld %lld\n", *count, offset);
29 if(offset >= rf->ndata){
30 r->ofcall.count = 0;
31 respond(r, nil);
32 return;
33 }
35 if(offset+count >= rf->ndata)
36 count = rf->ndata - offset;
38 memmove(r->ofcall.data, rf->data+offset, count);
39 r->ofcall.count = count;
40 respond(r, nil);
41 }
43 void
44 fswrite(Req *r)
45 {
46 void *v;
47 Ramfile *rf;
48 vlong offset;
49 long count;
51 rf = r->fid->file->aux;
52 offset = r->ifcall.offset;
53 count = r->ifcall.count;
55 if(offset+count >= rf->ndata){
56 v = realloc(rf->data, offset+count);
57 if(v == nil){
58 respond(r, Enomem);
59 return;
60 }
61 rf->data = v;
62 rf->ndata = offset+count;
63 r->fid->file->length = rf->ndata;
64 }
65 memmove(rf->data+offset, r->ifcall.data, count);
66 r->ofcall.count = count;
67 respond(r, nil);
68 }
70 void
71 fscreate(Req *r)
72 {
73 Ramfile *rf;
74 File *f;
76 if(f = createfile(r->fid->file, r->ifcall.name, r->fid->uid, r->ifcall.perm, nil)){
77 rf = emalloc9p(sizeof *rf);
78 f->aux = rf;
79 r->fid->file = f;
80 r->ofcall.qid = f->qid;
81 respond(r, nil);
82 return;
83 }
84 respond(r, Ebad);
85 }
87 void
88 fsopen(Req *r)
89 {
90 Ramfile *rf;
92 rf = r->fid->file->aux;
94 if(rf && (r->ifcall.mode&OTRUNC)){
95 rf->ndata = 0;
96 r->fid->file->length = 0;
97 }
99 respond(r, nil);
102 void
103 fsdestroyfile(File *f)
105 Ramfile *rf;
107 //fprint(2, "clunk\n");
108 rf = f->aux;
109 if(rf){
110 free(rf->data);
111 free(rf);
115 Srv fs = {
116 .open= fsopen,
117 .read= fsread,
118 .write= fswrite,
119 .create= fscreate,
120 };
122 void
123 usage(void)
125 fprint(2, "usage: ramfs [-D] [-s srvname] [-m mtpt]\n");
126 exits("usage");
129 void
130 main(int argc, char **argv)
132 char *srvname = nil;
133 char *mtpt = nil;
134 Qid q;
136 fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile);
137 q = fs.tree->root->qid;
139 ARGBEGIN{
140 case 'D':
141 chatty9p++;
142 break;
143 case 's':
144 srvname = EARGF(usage());
145 break;
146 case 'm':
147 mtpt = EARGF(usage());
148 break;
149 default:
150 usage();
151 }ARGEND;
153 if(argc)
154 usage();
156 if(chatty9p)
157 fprint(2, "ramsrv.nopipe %d srvname %s mtpt %s\n", fs.nopipe, srvname, mtpt);
158 if(srvname == nil && mtpt == nil)
159 sysfatal("you should at least specify a -s or -m option");
161 postmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
162 exits(0);