1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <fcall.h>
5 #include <thread.h>
6 #include <9p.h>
7
8 static char Ebad[] = "something bad happened";
9 static char Enomem[] = "no memory";
10
11 typedef struct Ramfile Ramfile;
12 struct Ramfile {
13 char *data;
14 int ndata;
15 };
16
17 void
fsread(Req * r)18 fsread(Req *r)
19 {
20 Ramfile *rf;
21 vlong offset;
22 long count;
23
24 rf = r->fid->file->aux;
25 offset = r->ifcall.offset;
26 count = r->ifcall.count;
27
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 }
34
35 if(offset+count >= rf->ndata)
36 count = rf->ndata - offset;
37
38 memmove(r->ofcall.data, rf->data+offset, count);
39 r->ofcall.count = count;
40 respond(r, nil);
41 }
42
43 void
fswrite(Req * r)44 fswrite(Req *r)
45 {
46 void *v;
47 Ramfile *rf;
48 vlong offset;
49 long count;
50
51 rf = r->fid->file->aux;
52 offset = r->ifcall.offset;
53 count = r->ifcall.count;
54
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 }
69
70 void
fscreate(Req * r)71 fscreate(Req *r)
72 {
73 Ramfile *rf;
74 File *f;
75
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 }
86
87 void
fsopen(Req * r)88 fsopen(Req *r)
89 {
90 Ramfile *rf;
91
92 rf = r->fid->file->aux;
93
94 if(rf && (r->ifcall.mode&OTRUNC)){
95 rf->ndata = 0;
96 r->fid->file->length = 0;
97 }
98
99 respond(r, nil);
100 }
101
102 void
fsdestroyfile(File * f)103 fsdestroyfile(File *f)
104 {
105 Ramfile *rf;
106
107 //fprint(2, "clunk\n");
108 rf = f->aux;
109 if(rf){
110 free(rf->data);
111 free(rf);
112 }
113 }
114
115 Srv fs = {
116 .open= fsopen,
117 .read= fsread,
118 .write= fswrite,
119 .create= fscreate,
120 };
121
122 void
usage(void)123 usage(void)
124 {
125 fprint(2, "usage: ramfs [-D] [-s srvname] [-m mtpt]\n");
126 exits("usage");
127 }
128
129 void
main(int argc,char ** argv)130 main(int argc, char **argv)
131 {
132 char *addr = nil;
133 char *srvname = nil;
134 char *mtpt = nil;
135 Qid q;
136
137 fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile);
138 q = fs.tree->root->qid;
139
140 ARGBEGIN{
141 case 'D':
142 chatty9p++;
143 break;
144 case 'a':
145 addr = EARGF(usage());
146 break;
147 case 's':
148 srvname = EARGF(usage());
149 break;
150 case 'm':
151 mtpt = EARGF(usage());
152 break;
153 default:
154 usage();
155 }ARGEND;
156
157 if(argc)
158 usage();
159
160 if(chatty9p)
161 fprint(2, "ramsrv.nopipe %d srvname %s mtpt %s\n", fs.nopipe, srvname, mtpt);
162 if(addr == nil && srvname == nil && mtpt == nil)
163 sysfatal("must specify -a, -s, or -m option");
164 if(addr)
165 listensrv(&fs, addr);
166
167 if(srvname || mtpt)
168 postmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
169 exits(0);
170 }
171