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 *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