fs.c (4746B)
1 #include <u.h> 2 #include <libc.h> 3 #include <fcall.h> 4 #include <thread.h> 5 #include <draw.h> 6 #include <9p.h> 7 8 #include "array.h" 9 #include "richterm.h" 10 11 Array *consbuf, *ctlbuf, *menubuf; 12 Channel *consc, *ctlc; 13 File *fsroot; 14 File *cons, *consctl, *ctl, *menu, *new, *text; 15 Reqqueue *rq; 16 17 void arrayopen(Req *); 18 void arrayread(Req *); 19 void arraywrite(Req *); 20 void consread(Req *); 21 void conswrite(Req *); 22 void ctlread(Req *); 23 void ctlwrite(Req *); 24 void delayedread(Req *); 25 void fs_destroyfid(Fid *); 26 void fs_flush(Req *); 27 void fs_open(Req *); 28 void fs_read(Req *); 29 void fs_write(Req *); 30 void fs_stat(Req *); 31 32 int 33 initfs(char *srvname) 34 { 35 static Srv srv = { 36 .open = fs_open, 37 .read = fs_read, 38 .write = fs_write, 39 .flush = fs_flush, 40 .stat = fs_stat, 41 .destroyfid = fs_destroyfid, 42 }; 43 consbuf = nil; 44 ctlbuf = nil; 45 rq = reqqueuecreate(); 46 menubuf = arraycreate(sizeof(char), 1024, nil); 47 consc = chancreate(sizeof(Array *), 1024); 48 ctlc = chancreate(sizeof(Array *), 8); 49 50 srv.tree = alloctree("richterm", "richterm", DMDIR|0555, nil); 51 fsroot = srv.tree->root; 52 53 cons = createfile(fsroot, "cons", "richterm", DMAPPEND|0666, 54 fauxalloc(nil, nil, consread, conswrite, nil, nil)); 55 56 consctl = createfile(fsroot, "consctl", "richterm", DMAPPEND|0666, 57 fauxalloc(nil, nil, nil, nil, nil, nil)); 58 59 ctl = createfile(fsroot, "ctl", "richterm", DMAPPEND|0666, 60 fauxalloc(nil, nil, ctlread, ctlwrite, nil, nil)); 61 62 text = createfile(fsroot, "text", "richterm", 0666, 63 fauxalloc(richdata, arrayopen, arrayread, arraywrite, nil, nil)); 64 text->length = richdata->count; 65 66 menu = createfile(fsroot, "menu", "richterm", 0666, 67 fauxalloc(menubuf, nil, arrayread, arraywrite, nil, nil)); 68 69 threadpostmountsrv(&srv, srvname, "/mnt/richterm", MREPL); 70 return 0; 71 } 72 73 Faux * 74 fauxalloc( 75 Array *data, 76 void (*open)(Req *), 77 void (*read)(Req *), 78 void (*write)(Req *), 79 void (*stat)(Req *), 80 void (*destroyfid)(Fid *)) 81 { 82 Faux *aux; 83 aux = mallocz(sizeof(Faux), 1); 84 *aux = (Faux) {data, open, read, write, stat, destroyfid}; 85 return aux; 86 } 87 88 void 89 fs_destroyfid(Fid *) 90 { 91 } 92 93 void 94 fs_open(Req *r) 95 { 96 Faux *aux = r->fid->file->aux; 97 if ((aux != nil) && (aux->open != nil)) aux->open(r); 98 else respond(r, nil); 99 } 100 101 void 102 fs_read(Req *r) 103 { 104 reqqueuepush(rq, r, delayedread); 105 } 106 107 void 108 fs_write(Req *r) 109 { 110 Faux *aux; 111 aux = r->fid->file->aux; 112 if (aux != nil) { 113 if (aux->write != nil) { 114 aux->write(r); 115 nbsend(redrawc, nil); 116 } 117 else respond(r, "no write"); 118 } else respond(r, nil); 119 } 120 121 void 122 fs_stat(Req *r) 123 { 124 Faux *aux = r->fid->file->aux; 125 if (aux != nil) { 126 if (aux->stat != nil) aux->stat(r); 127 else if (aux->data != nil) { 128 r->fid->file->length = aux->data->count; 129 r->d.length = aux->data->count; 130 respond(r, nil); 131 } 132 } else respond(r, nil); 133 } 134 135 void 136 fs_flush(Req *r) 137 { 138 respond(r, nil); 139 } 140 141 void 142 delayedread(Req *r) 143 { 144 Faux *aux; 145 aux = r->fid->file->aux; 146 if (aux != nil) { 147 if (aux->read != nil) aux->read(r); 148 else respond(r, "no read"); 149 } else respond(r, nil); 150 } 151 152 void 153 arrayopen(Req *r) 154 { 155 Array *data = ((Faux *)r->fid->file->aux)->data; 156 157 if ((r->ifcall.mode & OTRUNC) != 0) { 158 qlock(data->l); 159 data->count = 0; 160 qunlock(data->l); 161 r->fid->file->length = 0; 162 } 163 respond(r, nil); 164 } 165 166 void 167 arrayread(Req *r) 168 { 169 Array *data = ((Faux *)r->fid->file->aux)->data; 170 171 qlock(rich.l); 172 qlock(data->l); 173 readbuf(r, data->p, data->count); 174 qunlock(data->l); 175 qunlock(rich.l); 176 177 respond(r, nil); 178 } 179 180 void 181 arraywrite(Req *r) 182 { 183 Array *data = ((Faux *)r->fid->file->aux)->data; 184 185 long count = r->ifcall.count + r->ifcall.offset; 186 187 188 if (count > data->count) arraygrow(data, count - data->count, nil); 189 190 else data->count = count; 191 192 qlock(data->l); 193 194 memcpy(data->p + r->ifcall.offset, r->ifcall.data, r->ifcall.count); 195 qunlock(data->l); 196 197 r->ofcall.count = r->ifcall.count; 198 199 r->fid->file->length = data->count; 200 201 respond(r, nil); 202 } 203 204 void 205 consread(Req *r) 206 { 207 if (consbuf == nil) recv(consc, &consbuf); 208 r->ifcall.offset = 0; 209 readbuf(r, consbuf->p, consbuf->count); 210 if (arraydel(consbuf, 0, r->ofcall.count) != 0) 211 sysfatal("consread: %r"); 212 if (consbuf->count == 0) { 213 arrayfree(consbuf); 214 consbuf = nil; 215 } 216 217 respond(r, nil); 218 } 219 220 void 221 conswrite(Req *r) 222 { 223 Array *a; 224 a = arraycreate(sizeof(char), r->ifcall.count, nil); 225 arraygrow(a, r->ifcall.count, r->ifcall.data); 226 nbsend(insertc, &a); 227 r->ofcall.count = r->ifcall.count; 228 respond(r, nil); 229 } 230 231 void 232 ctlread(Req *r) 233 { 234 if (ctlbuf == nil) recv(ctlc, &ctlbuf); 235 if (ctlbuf == nil) sysfatal("ctlread: ctlbuf is nil: %r"); 236 r->ifcall.offset = 0; 237 readbuf(r, ctlbuf->p, ctlbuf->count); 238 if (arraydel(ctlbuf, 0, r->ofcall.count) != 0) 239 sysfatal("ctlread: %r"); 240 if (ctlbuf->count == 0) { 241 arrayfree(ctlbuf); 242 ctlbuf = nil; 243 } 244 245 respond(r, nil); 246 } 247 248 void 249 ctlwrite(Req *r) 250 { 251 respond(r, nil); 252 }