123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866 |
- implement Fsys;
- include "common.m";
- sys : Sys;
- styx : Styx;
- styxaux : Styxaux;
- acme : Acme;
- dat : Dat;
- utils : Utils;
- look : Look;
- windowm : Windowm;
- xfidm : Xfidm;
- QTDIR, QTFILE, QTAPPEND : import Sys;
- DMDIR, DMAPPEND, Qid, ORCLOSE, OTRUNC, OREAD, OWRITE, ORDWR, Dir : import Sys;
- sprint : import sys;
- MAXWELEM, Rerror : import Styx;
- Qdir,Qacme,Qcons,Qconsctl,Qdraw,Qeditout,Qindex,Qlabel,Qnew,QWaddr,QWbody,QWconsctl,QWctl,QWdata,QWeditout,QWevent,QWrdsel,QWwrsel,QWtag,QMAX : import Dat;
- TRUE, FALSE : import Dat;
- cxfidalloc, cerr : import dat;
- Mntdir, Fid, Dirtab, Lock, Ref, Smsg0 : import dat;
- Tmsg, Rmsg : import styx;
- msize, version, fid, uname, aname, newfid, name, mode, offset, count, setmode : import styxaux;
- Xfid : import xfidm;
- row : import dat;
- Column : import Columnm;
- Window : import windowm;
- lookid : import look;
- warning, error : import utils;
- init(mods : ref Dat->Mods)
- {
- messagesize = Styx->MAXRPC;
- sys = mods.sys;
- styx = mods.styx;
- styxaux = mods.styxaux;
- acme = mods.acme;
- dat = mods.dat;
- utils = mods.utils;
- look = mods.look;
- windowm = mods.windowm;
- xfidm = mods.xfidm;
- }
- sfd, cfd : ref Sys->FD;
- Nhash : con 16;
- DEBUG : con 0;
- fids := array[Nhash] of ref Fid;
- Eperm := "permission denied";
- Eexist := "file does not exist";
- Enotdir := "not a directory";
- dirtab := array[10] of {
- Dirtab ( ".", QTDIR, Qdir, 8r500|DMDIR ),
- Dirtab ( "acme", QTDIR, Qacme, 8r500|DMDIR ),
- Dirtab ( "cons", QTFILE, Qcons, 8r600 ),
- Dirtab ( "consctl", QTFILE, Qconsctl, 8r000 ),
- Dirtab ( "draw", QTDIR, Qdraw, 8r000|DMDIR ),
- Dirtab ( "editout", QTFILE, Qeditout, 8r200 ),
- Dirtab ( "index", QTFILE, Qindex, 8r400 ),
- Dirtab ( "label", QTFILE, Qlabel, 8r600 ),
- Dirtab ( "new", QTDIR, Qnew, 8r500|DMDIR ),
- Dirtab ( nil, 0, 0, 0 ),
- };
- dirtabw := array[12] of {
- Dirtab ( ".", QTDIR, Qdir, 8r500|DMDIR ),
- Dirtab ( "addr", QTFILE, QWaddr, 8r600 ),
- Dirtab ( "body", QTAPPEND, QWbody, 8r600|DMAPPEND ),
- Dirtab ( "ctl", QTFILE, QWctl, 8r600 ),
- Dirtab ( "consctl", QTFILE, QWconsctl, 8r200 ),
- Dirtab ( "data", QTFILE, QWdata, 8r600 ),
- Dirtab ( "editout", QTFILE, QWeditout, 8r200 ),
- Dirtab ( "event", QTFILE, QWevent, 8r600 ),
- Dirtab ( "rdsel", QTFILE, QWrdsel, 8r400 ),
- Dirtab ( "wrsel", QTFILE, QWwrsel, 8r200 ),
- Dirtab ( "tag", QTAPPEND, QWtag, 8r600|DMAPPEND ),
- Dirtab ( nil, 0, 0, 0 ),
- };
- Mnt : adt {
- qlock : ref Lock;
- id : int;
- md : ref Mntdir;
- };
- mnt : Mnt;
- user : string;
- clockfd : ref Sys->FD;
- closing := 0;
- fsysinit()
- {
- p : array of ref Sys->FD;
- p = array[2] of ref Sys->FD;
- if(sys->pipe(p) < 0)
- error("can't create pipe");
- cfd = p[0];
- sfd = p[1];
- clockfd = sys->open("/dev/time", Sys->OREAD);
- user = utils->getuser();
- if (user == nil)
- user = "Wile. E. Coyote";
- mnt.qlock = Lock.init();
- mnt.id = 0;
- spawn fsysproc();
- }
- fsyscfd() : int
- {
- return cfd.fd;
- }
- QID(w, q : int) : int
- {
- return (w<<8)|q;
- }
- FILE(q : Qid) : int
- {
- return int q.path & 16rFF;
- }
- WIN(q : Qid) : int
- {
- return (int q.path>>8) & 16rFFFFFF;
- }
- # nullsmsg : Smsg;
- nullsmsg0 : Smsg0;
- fsysproc()
- {
- n, ok : int;
- x : ref Xfid;
- f : ref Fid;
- t : Smsg0;
- acme->fsyspid = sys->pctl(0, nil);
- x = nil;
- for(;;){
- if(x == nil){
- cxfidalloc <-= nil;
- x = <-cxfidalloc;
- }
- n = sys->read(sfd, x.buf, messagesize);
- if(n <= 0) {
- if (closing)
- break;
- error("i/o error on server channel");
- }
- (ok, x.fcall) = Tmsg.unpack(x.buf[0:n]);
- if(ok < 0)
- error("convert error in convM2S");
- if(DEBUG)
- utils->debug(sprint("%d:%s\n", x.tid, x.fcall.text()));
- pick fc := x.fcall {
- Version =>
- f = nil;
- Auth =>
- f = nil;
- * =>
- f = allocfid(fid(x.fcall));
- }
- x.f = f;
- pick fc := x.fcall {
- Readerror => x = fsyserror();
- Flush => x = fsysflush(x);
- Version => x = fsysversion(x);
- Auth => x = fsysauth(x);
- Attach => x = fsysattach(x, f);
- Walk => x = fsyswalk(x, f);
- Open => x = fsysopen(x, f);
- Create => x = fsyscreate(x);
- Read => x = fsysread(x, f);
- Write => x = fsyswrite(x);
- Clunk => x = fsysclunk(x, f);
- Remove => x = fsysremove(x);
- Stat => x = fsysstat(x, f);
- Wstat => x = fsyswstat(x);
- # Clone => x = fsysclone(x, f);
- * =>
- x = respond(x, t, "bad fcall type");
- }
- }
- }
- fsysaddid(dir : string, ndir : int, incl : array of string, nincl : int) : ref Mntdir
- {
- m : ref Mntdir;
- id : int;
- mnt.qlock.lock();
- id = ++mnt.id;
- m = ref Mntdir;
- m.id = id;
- m.dir = dir;
- m.refs = 1; # one for Command, one will be incremented in attach
- m.ndir = ndir;
- m.next = mnt.md;
- m.incl = incl;
- m.nincl = nincl;
- mnt.md = m;
- mnt.qlock.unlock();
- return m;
- }
- fsysdelid(idm : ref Mntdir)
- {
- m, prev : ref Mntdir;
- i : int;
-
- if(idm == nil)
- return;
- mnt.qlock.lock();
- if(--idm.refs > 0){
- mnt.qlock.unlock();
- return;
- }
- prev = nil;
- for(m=mnt.md; m != nil; m=m.next){
- if(m == idm){
- if(prev != nil)
- prev.next = m.next;
- else
- mnt.md = m.next;
- for(i=0; i<m.nincl; i++)
- m.incl[i] = nil;
- m.incl = nil;
- m.dir = nil;
- m = nil;
- mnt.qlock.unlock();
- return;
- }
- prev = m;
- }
- mnt.qlock.unlock();
- buf := sys->sprint("fsysdelid: can't find id %d\n", idm.id);
- cerr <-= buf;
- }
- #
- # Called only in exec.l:run(), from a different FD group
- #
- fsysmount(dir : string, ndir : int, incl : array of string, nincl : int) : ref Mntdir
- {
- m : ref Mntdir;
- # close server side so don't hang if acme is half-exited
- # sfd = nil;
- m = fsysaddid(dir, ndir, incl, nincl);
- buf := sys->sprint("%d", m.id);
- if(sys->mount(cfd, nil, "/mnt/acme", Sys->MREPL, buf) < 0){
- fsysdelid(m);
- return nil;
- }
- # cfd = nil;
- sys->bind("/mnt/acme", "/chan", Sys->MBEFORE); # was MREPL
- if(sys->bind("/mnt/acme", "/dev", Sys->MBEFORE) < 0){
- fsysdelid(m);
- return nil;
- }
- return m;
- }
- fsysclose()
- {
- closing = 1;
- # sfd = cfd = nil;
- }
- respond(x : ref Xfid, t0 : Smsg0, err : string) : ref Xfid
- {
- t : ref Rmsg;
- # t = nullsmsg;
- tag := x.fcall.tag;
- # fid := fid(x.fcall);
- qid := t0.qid;
- if(err != nil)
- t = ref Rmsg.Error(tag, err);
- else
- pick fc := x.fcall {
- Readerror => t = ref Rmsg.Error(tag, err);
- Flush => t = ref Rmsg.Flush(tag);
- Version => t = ref Rmsg.Version(tag, t0.msize, t0.version);
- Auth => t = ref Rmsg.Auth(tag, qid);
- # Clone => t = ref Rmsg.Clone(tag, fid);
- Attach => t = ref Rmsg.Attach(tag, qid);
- Walk => t = ref Rmsg.Walk(tag, t0.qids);
- Open => t = ref Rmsg.Open(tag, qid, t0.iounit);
- Create => t = ref Rmsg.Create(tag, qid, 0);
- Read => if(t0.count == len t0.data)
- t = ref Rmsg.Read(tag, t0.data);
- else
- t = ref Rmsg.Read(tag, t0.data[0: t0.count]);
- Write => t = ref Rmsg.Write(tag, t0.count);
- Clunk => t = ref Rmsg.Clunk(tag);
- Remove => t = ref Rmsg.Remove(tag);
- Stat => t = ref Rmsg.Stat(tag, t0.stat);
- Wstat => t = ref Rmsg.Wstat(tag);
-
- }
- # t.qid = t0.qid;
- # t.count = t0.count;
- # t.data = t0.data;
- # t.stat = t0.stat;
- # t.fid = x.fcall.fid;
- # t.tag = x.fcall.tag;
- buf := t.pack();
- if(buf == nil)
- error("convert error in convS2M");
- if(sys->write(sfd, buf, len buf) != len buf)
- error("write error in respond");
- buf = nil;
- if(DEBUG)
- utils->debug(sprint("%d:r: %s\n", x.tid, t.text()));
- return x;
- }
- # fsysnop(x : ref Xfid) : ref Xfid
- # {
- # t : Smsg0;
- #
- # return respond(x, t, nil);
- # }
- fsyserror() : ref Xfid
- {
- error("sys error : Terror");
- return nil;
- }
- fsyssession(x : ref Xfid) : ref Xfid
- {
- t : Smsg0;
- # BUG: should shut everybody down ??
- t = nullsmsg0;
- return respond(x, t, nil);
- }
- fsysversion(x : ref Xfid) : ref Xfid
- {
- t : Smsg0;
- pick m := x.fcall {
- Version =>
- (t.msize, t.version) = styx->compatible(m, messagesize, nil);
- messagesize = t.msize;
- return respond(x, t, nil);
- }
- return respond(x, t, "acme: bad version");
- # ms := msize(x.fcall);
- # if(ms < 256)
- # return respond(x, t, "version: message size too small");
- # t.msize = messagesize = ms;
- # v := version(x.fcall);
- # if(len v < 6 || v[0: 6] != "9P2000")
- # return respond(x, t, "unrecognized 9P version");
- # t.version = "9P2000";
- # return respond(x, t, nil);
- }
- fsysauth(x : ref Xfid) : ref Xfid
- {
- t : Smsg0;
- return respond(x, t, "acme: authentication not required");
- }
- fsysflush(x : ref Xfid) : ref Xfid
- {
- x.c <-= Xfidm->Xflush;
- return nil;
- }
- fsysattach(x : ref Xfid, f : ref Fid) : ref Xfid
- {
- t : Smsg0;
- id : int;
- m : ref Mntdir;
- if (uname(x.fcall) != user)
- return respond(x, t, Eperm);
- f.busy = TRUE;
- f.open = FALSE;
- f.qid = (Qid)(big Qdir, 0, QTDIR);
- f.dir = dirtab;
- f.nrpart = 0;
- f.w = nil;
- t.qid = f.qid;
- f.mntdir = nil;
- id = int aname(x.fcall);
- mnt.qlock.lock();
- for(m=mnt.md; m != nil; m=m.next)
- if(m.id == id){
- f.mntdir = m;
- m.refs++;
- break;
- }
- if(m == nil)
- cerr <-= "unknown id in attach";
- mnt.qlock.unlock();
- return respond(x, t, nil);
- }
- fsyswalk(x : ref Xfid, f : ref Fid) : ref Xfid
- {
- t : Smsg0;
- c, i, j, id : int;
- path, qtype : int;
- d, dir : array of Dirtab;
- w : ref Window;
- nf : ref Fid;
- if(f.open)
- return respond(x, t, "walk of open file");
- if(fid(x.fcall) != newfid(x.fcall)){
- nf = allocfid(newfid(x.fcall));
- if(nf.busy)
- return respond(x, t, "newfid already in use");
- nf.busy = TRUE;
- nf.open = FALSE;
- nf.mntdir = f.mntdir;
- if(f.mntdir != nil)
- f.mntdir.refs++;
- nf.dir = f.dir;
- nf.qid = f.qid;
- nf.w = f.w;
- nf.nrpart = 0; # not open, so must be zero
- if(nf.w != nil)
- nf.w.refx.inc();
- f = nf; # walk f
- }
- qtype = QTFILE;
- wqids: list of Qid;
- err := string nil;
- id = WIN(f.qid);
- q := f.qid;
- names := styxaux->names(x.fcall);
- nwname := len names;
- if(nwname > 0){
- for(i = 0; i < nwname; i++){
- if((q.qtype & QTDIR) == 0){
- err = Enotdir;
- break;
- }
- name := names[i];
- if(name == ".."){
- path = Qdir;
- qtype = QTDIR;
- id = 0;
- if(w != nil){
- w.close();
- w = nil;
- }
- if(i == MAXWELEM){
- err = "name too long";
- break;
- }
- q.qtype = qtype;
- q.vers = 0;
- q.path = big QID(id, path);
- wqids = q :: wqids;
- continue;
- }
- # is it a numeric name?
- regular := 0;
- for(j=0; j < len name; j++) {
- c = name[j];
- if(c<'0' || '9'<c) {
- regular = 1;
- break;
- }
- }
- if (!regular) {
- # yes: it's a directory
- if(w != nil) # name has form 27/23; get out before losing w
- break;
- id = int name;
- row.qlock.lock();
- w = lookid(id, FALSE);
- if(w == nil){
- row.qlock.unlock();
- break;
- }
- w.refx.inc();
- path = Qdir;
- qtype = QTDIR;
- row.qlock.unlock();
- dir = dirtabw;
- if(i == MAXWELEM){
- err = "name too long";
- break;
- }
- q.qtype = qtype;
- q.vers = 0;
- q.path = big QID(id, path);
- wqids = q :: wqids;
- continue;
- }
- else {
- # if(FILE(f.qid) == Qacme) # empty directory
- # break;
- if(name == "new"){
- if(w != nil)
- error("w set in walk to new");
- cw := chan of ref Window;
- spawn x.walk(cw);
- w = <- cw;
- w.refx.inc();
- path = QID(w.id, Qdir);
- qtype = QTDIR;
- id = w.id;
- dir = dirtabw;
- # x.c <-= Xfidm->Xwalk;
- if(i == MAXWELEM){
- err = "name too long";
- break;
- }
- q.qtype = qtype;
- q.vers = 0;
- q.path = big QID(id, path);
- wqids = q :: wqids;
- continue;
- }
- if(id == 0)
- d = dirtab;
- else
- d = dirtabw;
- k := 1; # skip '.'
- found := 0;
- for( ; d[k].name != nil; k++){
- if(name == d[k].name){
- path = d[k].qid;
- qtype = d[k].qtype;
- dir = d[k:];
- if(i == MAXWELEM){
- err = "name too long";
- break;
- }
- q.qtype = qtype;
- q.vers = 0;
- q.path = big QID(id, path);
- wqids = q :: wqids;
- found = 1;
- break;
- }
- }
- if(found)
- continue;
- break; # file not found
- }
- }
- if(i == 0 && err == nil)
- err = Eexist;
- }
- nwqid := len wqids;
- if(nwqid > 0){
- t.qids = array[nwqid] of Qid;
- for(i = nwqid-1; i >= 0; i--){
- t.qids[i] = hd wqids;
- wqids = tl wqids;
- }
- }
- if(err != nil || nwqid < nwname){
- if(nf != nil){
- nf.busy = FALSE;
- fsysdelid(nf.mntdir);
- }
- }
- else if(nwqid == nwname){
- if(w != nil){
- f.w = w;
- w = nil;
- }
- if(dir != nil)
- f.dir = dir;
- f.qid = q;
- }
- if(w != nil)
- w.close();
- return respond(x, t, err);
- }
- fsysopen(x : ref Xfid, f : ref Fid) : ref Xfid
- {
- t : Smsg0;
- m : int;
- # can't truncate anything, so just disregard
- setmode(x.fcall, mode(x.fcall)&~OTRUNC);
- # can't execute or remove anything
- if(mode(x.fcall)&ORCLOSE)
- return respond(x, t, Eperm);
- case(mode(x.fcall)){
- OREAD =>
- m = 8r400;
- OWRITE =>
- m = 8r200;
- ORDWR =>
- m = 8r600;
- * =>
- return respond(x, t, Eperm);
- }
- if(((f.dir[0].perm&~(DMDIR|DMAPPEND))&m) != m)
- return respond(x, t, Eperm);
- x.c <-= Xfidm->Xopen;
- return nil;
- }
- fsyscreate(x : ref Xfid) : ref Xfid
- {
- t : Smsg0;
- return respond(x, t, Eperm);
- }
- idcmp(a, b : int) : int
- {
- return a-b;
- }
- qsort(a : array of int, n : int)
- {
- i, j : int;
- t : int;
- while(n > 1) {
- i = n>>1;
- t = a[0]; a[0] = a[i]; a[i] = t;
- i = 0;
- j = n;
- for(;;) {
- do
- i++;
- while(i < n && idcmp(a[i], a[0]) < 0);
- do
- j--;
- while(j > 0 && idcmp(a[j], a[0]) > 0);
- if(j < i)
- break;
- t = a[i]; a[i] = a[j]; a[j] = t;
- }
- t = a[0]; a[0] = a[j]; a[j] = t;
- n = n-j-1;
- if(j >= n) {
- qsort(a, j);
- a = a[j+1:];
- } else {
- qsort(a[j+1:], n);
- n = j;
- }
- }
- }
- fsysread(x : ref Xfid, f : ref Fid) : ref Xfid
- {
- t : Smsg0;
- b : array of byte;
- i, id, n, o, e, j, k, nids : int;
- ids : array of int;
- d : array of Dirtab;
- dt : Dirtab;
- c : ref Column;
- clock : int;
- b = nil;
- if(f.qid.qtype & QTDIR){
- # if(int offset(x.fcall) % DIRLEN)
- # return respond(x, t, "illegal offset in directory");
- if(FILE(f.qid) == Qacme){ # empty dir
- t.data = nil;
- t.count = 0;
- respond(x, t, nil);
- return x;
- }
- o = int offset(x.fcall);
- e = int offset(x.fcall)+count(x.fcall);
- clock = getclock();
- b = array[messagesize] of byte;
- id = WIN(f.qid);
- n = 0;
- if(id > 0)
- d = dirtabw;
- else
- d = dirtab;
- k = 1; # first entry is '.'
- leng := 0;
- for(i=0; d[k].name!=nil && i<e; i+=leng){
- bb := styx->packdir(dostat(WIN(x.f.qid), d[k], clock));
- leng = len bb;
- for (kk := 0; kk < leng; kk++)
- b[kk+n] = bb[kk];
- bb = nil;
- if(leng <= Styx->BIT16SZ)
- break;
- if(i >= o)
- n += leng;
- k++;
- }
- if(id == 0){
- row.qlock.lock();
- nids = 0;
- ids = nil;
- for(j=0; j<row.ncol; j++){
- c = row.col[j];
- for(k=0; k<c.nw; k++){
- oids := ids;
- ids = array[nids+1] of int;
- ids[0:] = oids[0:nids];
- oids = nil;
- ids[nids++] = c.w[k].id;
- }
- }
- row.qlock.unlock();
- qsort(ids, nids);
- j = 0;
- for(; j<nids && i<e; i+=leng){
- k = ids[j];
- dt.name = sys->sprint("%d", k);
- dt.qid = QID(k, 0);
- dt.qtype = QTDIR;
- dt.perm = DMDIR|8r700;
- bb := styx->packdir(dostat(k, dt, clock));
- leng = len bb;
- for (kk := 0; kk < leng; kk++)
- b[kk+n] = bb[kk];
- bb = nil;
- if(leng == 0)
- break;
- if(i >= o)
- n += leng;
- j++;
- }
- ids = nil;
- }
- t.data = b;
- t.count = n;
- respond(x, t, nil);
- b = nil;
- return x;
- }
- x.c <-= Xfidm->Xread;
- return nil;
- }
- fsyswrite(x : ref Xfid) : ref Xfid
- {
- x.c <-= Xfidm->Xwrite;
- return nil;
- }
- fsysclunk(x : ref Xfid, f : ref Fid) : ref Xfid
- {
- t : Smsg0;
- fsysdelid(f.mntdir);
- if(f.open){
- f.busy = FALSE;
- f.open = FALSE;
- x.c <-= Xfidm->Xclose;
- return nil;
- }
- if(f.w != nil)
- f.w.close();
- f.busy = FALSE;
- f.open = FALSE;
- return respond(x, t, nil);
- }
- fsysremove(x : ref Xfid) : ref Xfid
- {
- t : Smsg0;
- return respond(x, t, Eperm);
- }
- fsysstat(x : ref Xfid, f : ref Fid) : ref Xfid
- {
- t : Smsg0;
- t.stat = dostat(WIN(x.f.qid), f.dir[0], getclock());
- return respond(x, t, nil);
- }
- fsyswstat(x : ref Xfid) : ref Xfid
- {
- t : Smsg0;
- return respond(x, t, Eperm);
- }
- allocfid(fid : int) : ref Fid
- {
- f, ff : ref Fid;
- fh : int;
- ff = nil;
- fh = fid&(Nhash-1);
- for(f=fids[fh]; f != nil; f=f.next)
- if(f.fid == fid)
- return f;
- else if(ff==nil && f.busy==FALSE)
- ff = f;
- if(ff != nil){
- ff.fid = fid;
- return ff;
- }
- f = ref Fid;
- f.busy = FALSE;
- f.rpart = array[Sys->UTFmax] of byte;
- f.nrpart = 0;
- f.fid = fid;
- f.next = fids[fh];
- fids[fh] = f;
- return f;
- }
- cbuf := array[32] of byte;
- getclock() : int
- {
- sys->seek(clockfd, big 0, 0);
- n := sys->read(clockfd, cbuf, len cbuf);
- return int string cbuf[0:n];
- }
- dostat(id : int, dir : Dirtab, clock : int) : Sys->Dir
- {
- d : Dir;
- d.qid.path = big QID(id, dir.qid);
- d.qid.vers = 0;
- d.qid.qtype = dir.qtype;
- d.mode = dir.perm;
- d.length = big 0; # would be nice to do better
- d.name = dir.name;
- d.uid = user;
- d.gid = user;
- d.atime = clock;
- d.mtime = clock;
- d.dtype = d.dev = 0;
- return d;
- # buf := styx->convD2M(d);
- # d = nil;
- # return buf;
- }
|