plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

ramfs.c (2611B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <fcall.h>
      4 #include <thread.h>
      5 #include <9p.h>
      6 
      7 static char Ebad[] = "something bad happened";
      8 static char Enomem[] = "no memory";
      9 
     10 typedef struct Ramfile	Ramfile;
     11 struct Ramfile {
     12 	char *data;
     13 	int ndata;
     14 };
     15 
     16 void
     17 fsread(Req *r)
     18 {
     19 	Ramfile *rf;
     20 	vlong offset;
     21 	long count;
     22 
     23 	rf = r->fid->file->aux;
     24 	offset = r->ifcall.offset;
     25 	count = r->ifcall.count;
     26 
     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 	}
     33 
     34 	if(offset+count >= rf->ndata)
     35 		count = rf->ndata - offset;
     36 
     37 	memmove(r->ofcall.data, rf->data+offset, count);
     38 	r->ofcall.count = count;
     39 	respond(r, nil);
     40 }
     41 
     42 void
     43 fswrite(Req *r)
     44 {
     45 	void *v;
     46 	Ramfile *rf;
     47 	vlong offset;
     48 	long count;
     49 
     50 	rf = r->fid->file->aux;
     51 	offset = r->ifcall.offset;
     52 	count = r->ifcall.count;
     53 
     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 }
     68 
     69 void
     70 fscreate(Req *r)
     71 {
     72 	Ramfile *rf;
     73 	File *f;
     74 
     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 }
     85 
     86 void
     87 fsopen(Req *r)
     88 {
     89 	Ramfile *rf;
     90 
     91 	rf = r->fid->file->aux;
     92 
     93 	if(rf && (r->ifcall.mode&OTRUNC)){
     94 		rf->ndata = 0;
     95 		r->fid->file->dir.length = 0;
     96 	}
     97 
     98 	respond(r, nil);
     99 }
    100 
    101 void
    102 fsdestroyfile(File *f)
    103 {
    104 	Ramfile *rf;
    105 
    106 /*fprint(2, "clunk\n"); */
    107 	rf = f->aux;
    108 	if(rf){
    109 		free(rf->data);
    110 		free(rf);
    111 	}
    112 }
    113 
    114 Srv fs = {
    115 	.open=	fsopen,
    116 	.read=	fsread,
    117 	.write=	fswrite,
    118 	.create=	fscreate,
    119 };
    120 
    121 void
    122 usage(void)
    123 {
    124 	fprint(2, "usage: ramfs [-D] [-s srvname] [-m mtpt]\n");
    125 	threadexitsall("usage");
    126 }
    127 
    128 int
    129 threadmaybackground(void)
    130 {
    131 	return 1;
    132 }
    133 
    134 void
    135 threadmain(int argc, char **argv)
    136 {
    137 	char *srvname = nil;
    138 	char *mtpt = nil;
    139 	Qid q;
    140 
    141 	fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile);
    142 	q = fs.tree->root->dir.qid;
    143 
    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;
    157 
    158 	if(argc)
    159 		usage();
    160 
    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");
    165 
    166 	threadpostmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
    167 	threadexits(0);
    168 }