Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <fcall.h>
4 #include <thread.h>
5 #include <9p.h>
7 static char Ebad[] = "something bad happened";
8 static char Enomem[] = "no memory";
10 typedef struct Ramfile Ramfile;
11 struct Ramfile {
12 char *data;
13 int ndata;
14 };
16 void
17 fsread(Req *r)
18 {
19 Ramfile *rf;
20 vlong offset;
21 long count;
23 rf = r->fid->file->aux;
24 offset = r->ifcall.offset;
25 count = r->ifcall.count;
27 /*print("read %ld %lld\n", *count, offset); */
28 if(offset >= rf->ndata){
29 r->ofcall.count = 0;
30 respond(r, nil);
31 return;
32 }
34 if(offset+count >= rf->ndata)
35 count = rf->ndata - offset;
37 memmove(r->ofcall.data, rf->data+offset, count);
38 r->ofcall.count = count;
39 respond(r, nil);
40 }
42 void
43 fswrite(Req *r)
44 {
45 void *v;
46 Ramfile *rf;
47 vlong offset;
48 long count;
50 rf = r->fid->file->aux;
51 offset = r->ifcall.offset;
52 count = r->ifcall.count;
54 if(offset+count >= rf->ndata){
55 v = realloc(rf->data, offset+count);
56 if(v == nil){
57 respond(r, Enomem);
58 return;
59 }
60 rf->data = v;
61 rf->ndata = offset+count;
62 r->fid->file->dir.length = rf->ndata;
63 }
64 memmove(rf->data+offset, r->ifcall.data, count);
65 r->ofcall.count = count;
66 respond(r, nil);
67 }
69 void
70 fscreate(Req *r)
71 {
72 Ramfile *rf;
73 File *f;
75 if(f = createfile(r->fid->file, r->ifcall.name, r->fid->uid, r->ifcall.perm, nil)){
76 rf = emalloc9p(sizeof *rf);
77 f->aux = rf;
78 r->fid->file = f;
79 r->ofcall.qid = f->dir.qid;
80 respond(r, nil);
81 return;
82 }
83 respond(r, Ebad);
84 }
86 void
87 fsopen(Req *r)
88 {
89 Ramfile *rf;
91 rf = r->fid->file->aux;
93 if(rf && (r->ifcall.mode&OTRUNC)){
94 rf->ndata = 0;
95 r->fid->file->dir.length = 0;
96 }
98 respond(r, nil);
99 }
101 void
102 fsdestroyfile(File *f)
104 Ramfile *rf;
106 /*fprint(2, "clunk\n"); */
107 rf = f->aux;
108 if(rf){
109 free(rf->data);
110 free(rf);
114 Srv fs = {
115 .open= fsopen,
116 .read= fsread,
117 .write= fswrite,
118 .create= fscreate,
119 };
121 void
122 usage(void)
124 fprint(2, "usage: ramfs [-D] [-s srvname] [-m mtpt]\n");
125 threadexitsall("usage");
128 int
129 threadmaybackground(void)
131 return 1;
134 void
135 threadmain(int argc, char **argv)
137 char *srvname = nil;
138 char *mtpt = nil;
139 Qid q;
141 fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile);
142 q = fs.tree->root->dir.qid;
144 ARGBEGIN{
145 case 'D':
146 chatty9p++;
147 break;
148 case 's':
149 srvname = EARGF(usage());
150 break;
151 case 'm':
152 mtpt = EARGF(usage());
153 break;
154 default:
155 usage();
156 }ARGEND;
158 if(argc)
159 usage();
161 if(chatty9p)
162 fprint(2, "ramsrv.nopipe %d srvname %s mtpt %s\n", fs.nopipe, srvname, mtpt);
163 if(srvname == nil && mtpt == nil)
164 sysfatal("you should at least specify a -s or -m option");
166 threadpostmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
167 threadexits(0);