170 lines
2.6 KiB
C
170 lines
2.6 KiB
C
#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 *addr = nil;
|
|
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 'a':
|
|
addr = EARGF(usage());
|
|
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(addr == nil && srvname == nil && mtpt == nil)
|
|
sysfatal("must specify -a, -s, or -m option");
|
|
if(addr)
|
|
listensrv(&fs, addr);
|
|
|
|
if(srvname || mtpt)
|
|
postmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
|
|
exits(0);
|
|
}
|