Recompile [rsc] --rwxrwxr-x M 431581 glenda sys 101212 Oct 29 10:06 386/init /sys/src/libc/port/pool.c:dsize2bsize Handle character following : better. [rsc] --rw-rw-r-- M 431581 presotto sys 18532 Oct 29 10:05 sys/src/cmd/cb/cb.c /n/sourcesdump/2005/1029/plan9/sys/src/cmd/cb/cb.c:52,62 - /n/sourcesdump/2005/1030/plan9/sys/src/cmd/cb/cb.c:52,62 exits(0); } void - work(void){ - int c; + work(void) + { + int c, cc; struct keyw *lptr; char *pt; - char cc; int ct; while ((c = getch()) != Beof){ /n/sourcesdump/2005/1029/plan9/sys/src/cmd/cb/cb.c:471,476 - /n/sourcesdump/2005/1030/plan9/sys/src/cmd/cb/cb.c:471,477 putch(cc,NO); continue; } + unget(cc); if (question == 1){ question = 0; gotop(c); Keep children in create order. [rsc] --rw-rw-r-- M 431581 glenda sys 6695 Oct 29 10:54 sys/src/lib9p/file.c /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:10,20 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:10,27 * Always lock child then parent, never parent then child. * If holding the free file lock, do not lock any Files. */ - struct Filelist { + struct Filelist + { File *f; Filelist *link; }; + struct Readdir + { + File *dir; + Filelist *fl; + }; + static QLock filelk; static File *freefilelist; /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:67,72 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:74,112 qunlock(&filelk); } + static void + cleanfilelist(File *f) + { + Filelist **l; + Filelist *fl; + + /* + * can't delete filelist structures while there + * are open readers of this directory, because + * they might have references to the structures. + * instead, just leave the empty refs in the list + * until there is no activity and then clean up. + */ + if(f->readers.ref != 0) + return; + if(f->nxchild == 0) + return; + + /* + * no dir readers, file is locked, and + * there are empty entries in the file list. + * clean them out. + */ + for(l=&f->filelist; fl=*l; ){ + if(fl->f == nil){ + *l = (*l)->link; + free(fl); + }else + l = &(*l)->link; + } + f->nxchild = 0; + } + void closefile(File *f) { /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:125,134 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:165,177 fl->f = nil; fp->nchild--; + fp->nxchild++; f->parent = nil; - wunlock(fp); wunlock(f); + cleanfilelist(fp); + wunlock(fp); + closefile(fp); /* reference from child */ closefile(f); /* reference from tree */ closefile(f); /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:139,145 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:182,188 createfile(File *fp, char *name, char *uid, ulong perm, void *aux) { File *f; - Filelist *fl, *freel; + Filelist **l, *fl; Tree *t; if((fp->qid.type&QTDIR) == 0){ /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:147,170 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:190,215 return nil; } - freel = nil; wlock(fp); - for(fl=fp->filelist; fl; fl=fl->link){ - if(fl->f == nil) - freel = fl; - else if(strcmp(fl->f->name, name) == 0){ + /* + * We might encounter blank spots along the + * way due to deleted files that have not yet + * been flushed from the file list. Don't reuse + * those - some apps (e.g., omero) depend on + * the file order reflecting creation order. + * Always create at the end of the list. + */ + for(l=&fp->filelist; fl=*l; l=&fl->link){ + if(fl->f && strcmp(fl->f->name, name) == 0){ wunlock(fp); werrstr("file already exists"); return nil; } } + + fl = emalloc9p(sizeof *fl); + *l = fl; - if(freel == nil){ - freel = emalloc9p(sizeof *freel); - freel->link = fp->filelist; - fp->filelist = freel; - } - f = allocfile(); f->name = estrdup9p(name); f->uid = estrdup9p(uid ? uid : fp->uid); /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:193,199 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:238,244 incref(f); /* being returned */ incref(f); /* for the tree */ - freel->f = f; + fl->f = f; fp->nchild++; wunlock(fp); /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:245,251 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:290,296 else nexts = s+strlen(s); nf = walkfile1(f, s); - decref(f); + closefile(f); f = nf; if(f == nil) break; /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:323,332 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:368,373 free(t); } - struct Readdir { - Filelist *fl; - }; - Readdir* opendirfile(File *dir) { /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:340,349 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:381,394 r = emalloc9p(sizeof(*r)); /* - * This reference won't go away while we're using it - * since we are dir->rdir. + * This reference won't go away while we're + * using it because file list entries are not freed + * until the directory is removed and all refs to + * it (our fid is one!) have gone away. */ r->fl = dir->filelist; + r->dir = dir; + incref(&dir->readers); runlock(dir); return r; } /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:367,371 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:412,421 void closedirfile(Readdir *r) { + if(decref(&r->dir->readers) == 0){ + wlock(r->dir); + cleanfilelist(r->dir); + wunlock(r->dir); + } free(r); } [rsc] --rw-rw-r-- M 431581 glenda sys 16871 Oct 29 10:54 sys/src/lib9p/srv.c /n/sourcesdump/2005/1029/plan9/sys/src/lib9p/srv.c:218,224 - /n/sourcesdump/2005/1030/plan9/sys/src/lib9p/srv.c:218,224 r->fid->uid = estrdup9p(r->ifcall.uname); if(srv->tree){ r->fid->file = srv->tree->root; - /* BUG? incref(r->fid->file) ??? */ + incref(r->fid->file); r->ofcall.qid = r->fid->file->qid; r->fid->qid = r->ofcall.qid; } Allow rawon/rawoff during reads (for Plan B). [rsc] --rw-rw-r-- M 431581 glenda sys 22567 Oct 29 16:08 sys/src/9/port/devcons.c /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:25,31 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:25,31 QLock; int raw; /* true if we shouldn't process input */ - int ctl; /* number of opens to the control file */ + Ref ctl; /* number of opens to the control file */ int x; /* index into line */ char line[1024]; /* current input line */ /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:148,153 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:148,156 int m; char *t; + if(!islo()) + usewrite = 0; + /* * how many different output devices do we need? */ /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:408,413 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:411,417 xsummary(); ixsummary(); mallocsummary(); + // memorysummary(); pagersummary(); return; case 'd': /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:564,572 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:568,576 "cputime", {Qcputime}, 6*NUMSIZE, 0444, "drivers", {Qdrivers}, 0, 0444, "hostdomain", {Qhostdomain}, DOMLEN, 0664, - "hostowner", {Qhostowner}, 0, 0664, - "kmesg", {Qkmesg}, 0, 0440, - "kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440, + "hostowner", {Qhostowner}, 0, 0664, + "kmesg", {Qkmesg}, 0, 0440, + "kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440, "null", {Qnull}, 0, 0666, "osversion", {Qosversion}, 0, 0444, "pgrpid", {Qpgrpid}, NUMSIZE, 0444, /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:578,584 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:582,588 "sysname", {Qsysname}, 0, 0664, "sysstat", {Qsysstat}, 0, 0666, "time", {Qtime}, NUMSIZE+3*VLNUMSIZE, 0664, - "user", {Quser}, 0, 0666, + "user", {Quser}, 0, 0666, "zero", {Qzero}, 0, 0444, }; /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:648,656 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:652,658 c = devopen(c, omode, consdir, nelem(consdir), devgen); switch((ulong)c->qid.path){ case Qconsctl: - qlock(&kbd); - kbd.ctl++; - qunlock(&kbd); + incref(&kbd.ctl); break; case Qkprint: /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:680,689 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:682,689 /* last close of control file turns off raw */ case Qconsctl: if(c->flag&COPEN){ - qlock(&kbd); - if(--kbd.ctl == 0) + if(decref(&kbd.ctl) == 0) kbd.raw = 0; - qunlock(&kbd); } break; /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:702,715 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:702,715 { ulong l; Mach *mp; - char *b, *bp; + char *b, *bp, ch; char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */ - char *cbuf = buf; - int ch, i, k, id, eol; + int i, k, id, send; vlong offset = off; if(n <= 0) return n; + switch((ulong)c->qid.path){ case Qdir: return devdirread(c, buf, n, consdir, nelem(consdir), devgen); /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:720,766 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:720,759 qunlock(&kbd); nexterror(); } - if(kbd.raw) { - if(qcanread(lineq)) - n = qread(lineq, buf, n); - else { - /* read as much as possible */ - do { - i = qread(kbdq, cbuf, n); - cbuf += i; - n -= i; - } while (n>0 && qcanread(kbdq)); - n = cbuf - (char*)buf; - } - } else { - while(!qcanread(lineq)) { - qread(kbdq, &kbd.line[kbd.x], 1); - ch = kbd.line[kbd.x]; - eol = 0; + while(!qcanread(lineq)){ + qread(kbdq, &ch, 1); + send = 0; + if(ch == 0){ + /* flush output on rawoff -> rawon */ + if(kbd.x > 0) + send = !qcanread(kbdq); + }else if(kbd.raw){ + kbd.line[kbd.x++] = ch; + send = !qcanread(kbdq); + }else{ switch(ch){ case '\b': - if(kbd.x) + if(kbd.x > 0) kbd.x--; break; - case 0x15: + case 0x15: /* ^U */ kbd.x = 0; break; case '\n': - case 0x04: - eol = 1; + case 0x04: /* ^D */ + send = 1; default: - kbd.line[kbd.x++] = ch; + if(ch != 0x04) + kbd.line[kbd.x++] = ch; break; } - if(kbd.x == sizeof(kbd.line) || eol){ - if(ch == 0x04) - kbd.x--; - qwrite(lineq, kbd.line, kbd.x); - kbd.x = 0; - } } - n = qread(lineq, buf, n); + if(send || kbd.x == sizeof kbd.line){ + qwrite(lineq, kbd.line, kbd.x); + kbd.x = 0; + } } + n = qread(lineq, buf, n); qunlock(&kbd); poperror(); return n; /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:932,947 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:925,943 static long conswrite(Chan *c, void *va, long n, vlong off) { - char buf[256]; + char buf[256], ch; long l, bp; - char *a = va; + char *a; Mach *mp; int id, fd; Chan *swc; - ulong offset = off; + ulong offset; Cmdbuf *cb; Cmdtab *ct; + a = va; + offset = off; + switch((ulong)c->qid.path){ case Qcons: /* /n/sourcesdump/2005/1029/plan9/sys/src/9/port/devcons.c:967,982 - /n/sourcesdump/2005/1030/plan9/sys/src/9/port/devcons.c:963,976 for(a = buf; a;){ if(strncmp(a, "rawon", 5) == 0){ qlock(&kbd); - if(kbd.x){ - qwrite(kbdq, kbd.line, kbd.x); - kbd.x = 0; - } kbd.raw = 1; + /* clumsy hack - wake up reader */ + ch = 0; + qwrite(kbdq, &ch, 1); qunlock(&kbd); } else if(strncmp(a, "rawoff", 6) == 0){ qlock(&kbd); kbd.raw = 0; - kbd.x = 0; qunlock(&kbd); } else if(strncmp(a, "ctlpon", 6) == 0){ kbd.ctlpoff = 0; Explicitly use small cache. [rsc] --rwxrwxr-x M 431581 rsc sys 2518 Oct 29 17:40 sys/lib/dist/pc/inst/mountfossil /n/sourcesdump/2005/1029/plan9/sys/lib/dist/pc/inst/mountfossil:20,26 - /n/sourcesdump/2005/1030/plan9/sys/lib/dist/pc/inst/mountfossil:20,26 if(! ps | grep -s ' fossil$'){ echo 'srv -p fscons' > /env/fossilconf echo 'srv -AP fossil' >> /env/fossilconf - fossil/conf $fossil | sed 's/^fsys main open .*/& -AWVP/' | + fossil/conf $fossil | sed 's/^fsys main open .*/& -c 100 -AWVP/' | sed 's/^fsys main snaptime .*//' >> /env/fossilconf if(! logprog fossil/fossil -c .' /env/fossilconf'>>[2]/srv/log){ echo 'fossil: '^$status