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 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 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 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 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 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 123 usage(void) 124 { 125 fprint(2, "usage: ramfs [-D] [-s srvname] [-m mtpt]\n"); 126 exits("usage"); 127 } 128 129 void 130 main(int argc, char **argv) 131 { 132 char *srvname = nil; 133 char *mtpt = nil; 134 Qid q; 135 136 fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile); 137 q = fs.tree->root->qid; 138 139 ARGBEGIN{ 140 case 'D': 141 chatty9p++; 142 break; 143 case 's': 144 srvname = EARGF(usage()); 145 break; 146 case 'm': 147 mtpt = EARGF(usage()); 148 break; 149 default: 150 usage(); 151 }ARGEND; 152 153 if(argc) 154 usage(); 155 156 if(chatty9p) 157 fprint(2, "ramsrv.nopipe %d srvname %s mtpt %s\n", fs.nopipe, srvname, mtpt); 158 if(srvname == nil && mtpt == nil) 159 sysfatal("you should at least specify a -s or -m option"); 160 161 postmountsrv(&fs, srvname, mtpt, MREPL|MCREATE); 162 exits(0); 163 } 164