xref: /plan9/sys/src/lib9p/ramfs.c (revision 22a127bbfe4dd304949cc596400de973c0138e31)
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