commit 32f69c36e0eec1227934bbd34854bfebd88686f2 from: rsc date: Thu Dec 11 17:48:38 2003 UTC Add support for user-level 9P servers/clients and various bug fixes to go with them. commit - ac244f8d287a6119155ea672c8fd13c487c5e4c7 commit + 32f69c36e0eec1227934bbd34854bfebd88686f2 blob - 411bcef2dc8dcdafbe7c838331f4b424d064f9e6 blob + fb45d3e443198facb1a26c88517eea22aaa795b7 --- bin/B +++ bin/B @@ -6,6 +6,12 @@ then exit 1 fi +for i +do + plumb $i +done +exit 0 + if [ "x$DISPLAY" = "x" ] then sam="/tmp/.sam.$USER" blob - f85487bd7af777d557aab3eaa0a53cb73dbe237d blob + 893b05044a117aa4299923210118859bd0e49d52 --- include/fcall.h +++ include/fcall.h @@ -40,6 +40,7 @@ struct Fcall char *data; /* Twrite, Rread */ ushort nstat; /* Twstat, Rstat */ uchar *stat; /* Twstat, Rstat */ + int unixfd; /* Ropenfd */ } Fcall; @@ -100,6 +101,9 @@ enum Twstat = 126, Rwstat, Tmax, + + Topenfd = 98, + Ropenfd, }; uint convM2S(uchar*, uint, Fcall*); blob - 219b2774a5a98dbd58e8e9b4ee871215fec510fa blob + 384427091b538e0832f96ee31998a4d1a03bfeda --- include/fs.h +++ include/fs.h @@ -12,7 +12,7 @@ typedef struct Fsys Fsys; typedef struct Fid Fid; Fsys *fsinit(int); -Fsys *fsmount(int); +Fsys *fsmount(int, char*); int fsversion(Fsys*, int, char*, int); Fid *fsauth(Fsys*, char*); @@ -34,6 +34,7 @@ struct Dir *fsdirfstat(Fid*); int fsdirwstat(Fsys*, char*, struct Dir*); int fsdirfwstat(Fid*, struct Dir*); Fid *fsroot(Fsys*); +Fsys *nsmount(char*, char*); #ifdef __cplusplus } blob - ce5187cdb5a3f633f69dbf128f9404f342db3e8d blob + de082499cd29888671616f284a6fea17aa7f7ecf --- include/lib9.h +++ include/lib9.h @@ -194,6 +194,7 @@ extern int isupperrune(Rune); * extern void* malloc(ulong); */ +extern void* p9malloc(ulong); extern void* mallocz(ulong, int); /* extern void free(void*); @@ -208,6 +209,9 @@ extern ulong getrealloctag(void*); /* extern void* malloctopoolblock(void*); */ +#ifndef NOPLAN9DEFINES +#define malloc p9malloc +#endif /* * print routines (provided by ) @@ -442,6 +446,7 @@ extern void exits(char*); extern double frexp(double, int*); extern ulong getcallerpc(void*); extern char* p9getenv(char*); +extern int p9putenv(char*, char*); extern int getfields(char*, char**, int, int, char*); extern int gettokens(char *, char **, int, char *); extern char* getuser(void); @@ -482,6 +487,7 @@ extern long time(long*); #define longjmp p9longjmp #undef setjmp #define setjmp p9setjmp +#define putenv p9putenv #define notejmp p9notejmp #define jmp_buf p9jmp_buf #endif @@ -728,14 +734,14 @@ struct IOchunk extern void _exits(char*); extern void abort(void); -/* extern int access(char*, int); */ +extern int p9access(char*, int); extern long p9alarm(ulong); extern int await(char*, int); /* extern int bind(char*, char*, int); give up */ /* extern int brk(void*); */ -/* extern int chdir(char*); */ +extern int p9chdir(char*); extern int close(int); -extern int create(char*, int, ulong); +extern int p9create(char*, int, ulong); extern int p9dup(int, int); extern int errstr(char*, uint); extern int p9exec(char*, char*[]); @@ -752,9 +758,9 @@ extern int unmount(char*, char*); */ extern int noted(int); extern int notify(void(*)(void*, char*)); -/* extern int open(char*, int); */ +extern int p9open(char*, int); extern int fd2path(int, char*, int); -extern int pipe(int*); +extern int p9pipe(int*); /* * use defs from extern long pread(int, void*, long, vlong); @@ -796,6 +802,10 @@ extern ulong rendezvous(ulong, ulong); #define wait p9wait #define waitpid p9waitpid #define rfork p9rfork +#define access p9access +#define create p9create +#define open p9open +#define pipe p9pipe #endif extern Dir* dirstat(char*); @@ -810,6 +820,10 @@ extern long dirreadall(int, Dir**); extern void rerrstr(char*, uint); extern char* sysname(void); extern void werrstr(char*, ...); +extern char* getns(void); +extern int sendfd(int, int); +extern int recvfd(int); +extern int post9pservice(int, char*); /* external names that we don't want to step on */ #ifndef NOPLAN9DEFINES blob - e9dc96e031bc83452a1ba63890272997a0a4a26f blob + 0eb02b5291e09555a3a08f92682fa97b74a4cc1c --- include/thread.h +++ include/thread.h @@ -79,8 +79,8 @@ int nbsendul(Channel *c, unsigned long v); int proccreate(void (*f)(void *arg), void *arg, unsigned int stacksize); int procrfork(void (*f)(void *arg), void *arg, unsigned int stacksize, int flag); void** procdata(void); -void procexec(Channel *, char *, char *[]); -void procexecl(Channel *, char *, ...); +void procexec(Channel *, int[3], char *, char *[]); +void procexecl(Channel *, int[3], char *, ...); int recv(Channel *c, void *v); void* recvp(Channel *c); unsigned long recvul(Channel *c); blob - a065799e50b210871a42023198f377a7b91f9c1a blob + 918cc51b12f20057a0e9fc5d864ed3eb0217c8bd --- plumb/basic +++ plumb/basic @@ -38,7 +38,8 @@ data matches '[a-zA-Z¡-￿0-9_\-./]+' data matches '([a-zA-Z¡-￿0-9_\-./]+)\.(jpe?g|JPE?G|gif|GIF|tiff?|TIFF?|ppm|bit)' arg isfile $0 plumb to image -plumb client page -wi +plumb start qiv -t $1 +# plumb client page -wi # postscript/pdf/dvi go to page but not over the a plumb port # the port is here for reference but is unused @@ -47,7 +48,8 @@ data matches '[a-zA-Z¡-￿0-9_\-./]+' data matches '([a-zA-Z¡-￿0-9_\-./]+)\.(ps|PS|eps|EPS|pdf|PDF|dvi|DVI)' arg isfile $0 plumb to postscript -plumb start page -w $file +plumb start gv $file +# plumb start page -w $file # existing files, possibly tagged by line number, go to editor type is text @@ -56,8 +58,7 @@ arg isfile $1 data set $file attr add addr=$3 plumb to edit -plumb start /usr/local/plan9/bin/B $file:$3 -# plumb client window $editor +plumb client $editor # .h files are looked up in /usr/include and passed to edit type is text @@ -66,8 +67,7 @@ arg isfile /usr/include/$1 data set $file attr add addr=$3 plumb to edit -plumb start /usr/local/plan9/bin/B $file:$3 -# plumb client window $editor +plumb client $editor # .h files are looked up in /usr/local/include and passed to edit type is text @@ -76,8 +76,7 @@ arg isfile /usr/local/include/$1 data set $file attr add addr=$3 plumb to edit -plumb start /usr/local/plan9/bin/B $file:$3 -# plumb client window $editor +plumb client $editor # .h files are looked up in /usr/local/plan9/include and passed to edit type is text @@ -86,8 +85,7 @@ arg isfile /usr/local/plan9/include/$1 data set $file attr add addr=$3 plumb to edit -plumb start /usr/local/plan9/bin/B $file:$3 -# plumb client window $editor +plumb client $editor # .m files are looked up in /sys/module and passed to edit type is text @@ -96,8 +94,7 @@ arg isfile /sys/module/$1 data set $file attr add addr=$3 plumb to edit -plumb start /usr/local/plan9/bin/B $file:$3 -# plumb client window $editor +plumb client window $editor # faces -> new mail window for message type is text @@ -113,13 +110,14 @@ plumb start rc -c 'man '$2' '$1' >[2=1] | plumb -i -d # start rule for images without known suffixes dst is image +arg isfile $data plumb to image -plumb client page -wi +plumb start qiv -t $data # start rule for postscript without known suffixes dst is postscript arg isfile $data -plumb start page -w $data +plumb start gv $data type is text data matches 'Local (.*)' blob - 7c018c34b542cbfe666ab884688d000234dd6040 blob + e94817460c1546239e58389fd1ed8431ca873adb --- src/cmd/9p.c +++ src/cmd/9p.c @@ -11,7 +11,9 @@ usage(void) fprint(2, "usage: 9p [-a address] cmd args...\n"); fprint(2, "possible cmds:\n"); fprint(2, " read name\n"); + fprint(2, " readfd name\n"); fprint(2, " write name\n"); + fprint(2, " writefd name\n"); fprint(2, " stat name\n"); // fprint(2, " ls name\n"); fprint(2, "without -a, name elem/path means /path on server unix!$ns/elem\n"); @@ -20,6 +22,8 @@ usage(void) void xread(int, char**); void xwrite(int, char**); +void xreadfd(int, char**); +void xwritefd(int, char**); void xstat(int, char**); void xls(int, char**); @@ -29,6 +33,8 @@ struct { } cmds[] = { "read", xread, "write", xwrite, + "readfd", xreadfd, + "writefd", xwritefd, "stat", xstat, // "ls", xls, }; @@ -64,7 +70,6 @@ Fsys* xparse(char *name, char **path) { int fd; - char *ns; char *p; Fsys *fs; @@ -75,22 +80,17 @@ xparse(char *name, char **path) else *p++ = 0; *path = p; - if(*name == 0) - usage(); - ns = getenv("ns"); - if(ns == nil) - sysfatal("ns not set"); - addr = smprint("unix!%s/%s", ns, name); - if(addr == nil) - sysfatal("out of memory"); - }else + fs = nsmount(name, ""); + if(fs == nil) + sysfatal("mount: %r"); + }else{ *path = name; - - fprint(2, "dial %s...", addr); - if((fd = dial(addr, nil, nil, nil)) < 0) - sysfatal("dial: %r"); - if((fs = fsmount(fd)) == nil) - sysfatal("fsmount: %r"); + fprint(2, "dial %s...", addr); + if((fd = dial(addr, nil, nil, nil)) < 0) + sysfatal("dial: %r"); + if((fs = fsmount(fd, "")) == nil) + sysfatal("fsmount: %r"); + } return fs; } @@ -120,6 +120,15 @@ xopen(char *name, int mode) return fid; } +int +xopenfd(char *name, int mode) +{ + Fsys *fs; + + fs = xparse(name, &name); + return fsopenfd(fs, name, mode); +} + void xread(int argc, char **argv) { @@ -144,6 +153,29 @@ xread(int argc, char **argv) } void +xreadfd(int argc, char **argv) +{ + char buf[1024]; + int n; + int fd; + + ARGBEGIN{ + default: + usage(); + }ARGEND + + if(argc != 1) + usage(); + + fd = xopenfd(argv[0], OREAD); + while((n = read(fd, buf, sizeof buf)) > 0) + write(1, buf, n); + if(n < 0) + sysfatal("read error: %r"); + exits(0); +} + +void xwrite(int argc, char **argv) { char buf[1024]; @@ -168,6 +200,30 @@ xwrite(int argc, char **argv) } void +xwritefd(int argc, char **argv) +{ + char buf[1024]; + int n; + int fd; + + ARGBEGIN{ + default: + usage(); + }ARGEND + + if(argc != 1) + usage(); + + fd = xopenfd(argv[0], OWRITE|OTRUNC); + while((n = read(0, buf, sizeof buf)) > 0) + if(write(fd, buf, n) != n) + sysfatal("write error: %r"); + if(n < 0) + sysfatal("read error: %r"); + exits(0); +} + +void xstat(int argc, char **argv) { Dir *d; blob - ad77236e85e4b534256a2917fb0056b00d60c91a blob + c33beb142926698c48fc59922888ed08c1937136 --- src/cmd/9pserve.c +++ src/cmd/9pserve.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include enum { @@ -38,6 +40,7 @@ struct Msg int ref; int ctag; int tag; + int isopenfd; Fcall tx; Fcall rx; Fid *fid; @@ -52,6 +55,8 @@ struct Msg struct Conn { int fd; + int fdmode; + Fid *fdfid; int nmsg; int nfid; Channel *inc; @@ -89,7 +94,7 @@ void *erealloc(void*, int); Queue *qalloc(void); int sendq(Queue*, void*); void *recvq(Queue*); -void selectthread(void*); +void pollthread(void*); void connthread(void*); void connoutthread(void*); void listenthread(void*); @@ -100,6 +105,10 @@ int tlisten(char*, char*); int taccept(int, char*); int iolisten(Ioproc*, char*, char*); int ioaccept(Ioproc*, int, char*); +int iorecvfd(Ioproc*, int); +int iosendfd(Ioproc*, int, int); +void mainproc(void*); +int ignorepipe(void*, char*); void usage(void) @@ -110,14 +119,13 @@ usage(void) } uchar vbuf[128]; - +extern int _threaddebuglevel; void threadmain(int argc, char **argv) { char *file; - int n; - Fcall f; + if(verbose) fprint(2, "9pserve running\n"); ARGBEGIN{ default: usage(); @@ -142,6 +150,20 @@ threadmain(int argc, char **argv) if((afd = announce(addr, adir)) < 0) sysfatal("announce %s: %r", addr); + proccreate(mainproc, nil, STACK); + threadexits(0); +} + +void +mainproc(void *v) +{ + int n; + Fcall f; + USED(v); + + yield(); /* let threadmain exit */ + + atnotify(ignorepipe, 1); fmtinstall('D', dirfmt); fmtinstall('M', dirmodefmt); fmtinstall('F', fcallfmt); @@ -150,10 +172,6 @@ threadmain(int argc, char **argv) outq = qalloc(); inq = qalloc(); -// threadcreateidle(selectthread, nil, STACK); - threadcreate(inputthread, nil, STACK); - threadcreate(outputthread, nil, STACK); - f.type = Tversion; f.version = "9P2000"; f.msize = 8192; @@ -165,9 +183,24 @@ threadmain(int argc, char **argv) if(convM2S(vbuf, n, &f) != n) sysfatal("convM2S failure"); if(verbose > 1) fprint(2, "* -> %F\n", &f); + + threadcreate(inputthread, nil, STACK); + threadcreate(outputthread, nil, STACK); threadcreate(listenthread, nil, STACK); + threadcreateidle(pollthread, nil, STACK); + threadexits(0); } +int +ignorepipe(void *v, char *s) +{ + USED(v); + if(strcmp(s, "sys: write on closed pipe") == 0) + return 1; + fprint(2, "msg: %s\n", s); + return 0; +} + void listenthread(void *arg) { @@ -178,10 +211,6 @@ listenthread(void *arg) USED(arg); for(;;){ c = emalloc(sizeof(Conn)); - c->inc = chancreate(sizeof(void*), 0); - c->internal = chancreate(sizeof(void*), 0); - c->inq = qalloc(); - c->outq = qalloc(); c->fd = iolisten(io, adir, c->dir); if(c->fd < 0){ if(verbose) fprint(2, "listen: %r\n"); @@ -189,13 +218,17 @@ listenthread(void *arg) free(c); return; } + c->inc = chancreate(sizeof(void*), 0); + c->internal = chancreate(sizeof(void*), 0); + c->inq = qalloc(); + c->outq = qalloc(); if(verbose) fprint(2, "incoming call on %s\n", c->dir); threadcreate(connthread, c, STACK); } } void -sendmsg(Msg *m) +send9pmsg(Msg *m) { int n, nn; @@ -226,7 +259,7 @@ err(Msg *m, char *ename) m->rx.type = Rerror; m->rx.ename = ename; m->rx.tag = m->tx.tag; - sendmsg(m); + send9pmsg(m); } void @@ -250,7 +283,7 @@ connthread(void *arg) c->fd = fd; threadcreate(connoutthread, c, STACK); while((m = mread9p(io, c->fd)) != nil){ - if(verbose > 1) fprint(2, "%s -> %F\n", c->dir, &m->tx); + if(verbose > 1) fprint(2, "fd#%d -> %F\n", c->fd, &m->tx); m->c = c; m->ctag = m->tx.tag; c->nmsg++; @@ -267,13 +300,13 @@ connthread(void *arg) m->rx.msize = 8192; m->rx.version = "9P2000"; m->rx.type = Rversion; - sendmsg(m); + send9pmsg(m); continue; case Tflush: if((m->oldm = gethash(c->tag, m->tx.oldtag)) == nil){ m->rx.tag = m->tx.tag; m->rx.type = Rflush; - sendmsg(m); + send9pmsg(m); continue; } m->oldm->ref++; @@ -318,6 +351,15 @@ connthread(void *arg) } m->afid->ref++; break; + case Topenfd: + if(m->tx.mode != OREAD && (m->tx.mode&~OTRUNC) != OWRITE){ + err(m, "openfd mode must be OREAD or OWRITE"); + continue; + } + m->isopenfd = 1; + m->tx.type = Topen; + m->tpkt[4] = Topen; + /* fall through */ case Tcreate: case Topen: case Tclunk: @@ -363,6 +405,7 @@ connthread(void *arg) m = msgnew(); m->internal = 1; m->c = c; + c->nmsg++; m->tx.type = Tflush; m->tx.tag = m->tag; m->tx.oldtag = om->tag; @@ -371,7 +414,9 @@ connthread(void *arg) m->ref++; /* for outq */ sendomsg(m); recvp(c->internal); - msgput(m); + msgput(m); /* got from recvp */ + msgput(m); /* got from msgnew */ + msgput(om); /* got from hash table */ } } @@ -382,6 +427,7 @@ connthread(void *arg) m = msgnew(); m->internal = 1; m->c = c; + c->nmsg++; m->tx.type = Tclunk; m->tx.tag = m->tag; m->tx.fid = f->fid; @@ -390,7 +436,9 @@ connthread(void *arg) m->ref++; sendomsg(m); recvp(c->internal); - msgput(m); + msgput(m); /* got from recvp */ + msgput(m); /* got from msgnew */ + fidput(f); /* got from hash table */ } } @@ -398,9 +446,157 @@ out: assert(c->nmsg == 0); assert(c->nfid == 0); close(c->fd); + chanfree(c->internal); + c->internal = 0; + chanfree(c->inc); + c->inc = 0; + free(c->inq); + c->inq = 0; + free(c->outq); + c->outq = 0; free(c); } + +static void +openfdthread(void *v) +{ + Conn *c; + Fid *fid; + Msg *m; + int n; + vlong tot; + Ioproc *io; + char buf[1024]; + + c = v; + fid = c->fdfid; + io = ioproc(); + + tot = 0; + if(c->fdmode == OREAD){ + for(;;){ + if(verbose) fprint(2, "tread..."); + m = msgnew(); + m->internal = 1; + m->c = c; + m->tx.type = Tread; + m->tx.count = 8192; + m->tx.fid = fid->fid; + m->tx.tag = m->tag; + m->tx.offset = tot; + m->fid = fid; + fid->ref++; + m->ref++; + sendomsg(m); + recvp(c->internal); + if(m->rx.type == Rerror) + break; + if(m->rx.count == 0) + break; + tot += m->rx.count; + if(iowrite(io, c->fd, m->rx.data, m->rx.count) != m->rx.count) + break; + msgput(m); + msgput(m); + } + }else{ + for(;;){ + if(verbose) fprint(2, "twrite..."); + if((n=ioread(io, c->fd, buf, sizeof buf)) <= 0){ + m = nil; + break; + } + m = msgnew(); + m->internal = 1; + m->c = c; + m->tx.type = Twrite; + m->tx.fid = fid->fid; + m->tx.data = buf; + m->tx.count = n; + m->tx.tag = m->tag; + m->tx.offset = tot; + m->fid = fid; + fid->ref++; + m->ref++; + sendomsg(m); + recvp(c->internal); + if(m->rx.type == Rerror) + break; + tot = n; + msgput(m); + msgput(m); + } + } + if(verbose) fprint(2, "eof on %d fid %d\n", c->fd, fid->fid); + close(c->fd); + closeioproc(io); + if(m){ + msgput(m); + msgput(m); + } + m = msgnew(); + m->internal = 1; + m->c = c; + m->tx.type = Tclunk; + m->tx.fid = fid->fid; + m->fid = fid; + fid->ref++; + m->ref++; + sendomsg(m); + recvp(c->internal); + msgput(m); + msgput(m); + fidput(fid); + c->fdfid = nil; + chanfree(c->internal); + c->internal = 0; + free(c); +} +int +xopenfd(Msg *m) +{ + char errs[ERRMAX]; + int n, p[2]; + Conn *nc; + + if(pipe(p) < 0){ + rerrstr(errs, sizeof errs); + err(m, errs); + } + if(verbose) fprint(2, "xopen pipe %d %d...", p[0], p[1]); + + /* now we're committed. */ + + /* a new connection for this fid */ + nc = emalloc(sizeof(Conn)); + nc->internal = chancreate(sizeof(void*), 0); + + /* a ref for us */ + nc->fdfid = m->fid; + m->fid->ref++; + nc->fdmode = m->tx.mode; + nc->fd = p[0]; + + /* clunk fid from other connection */ + if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0) + fidput(m->fid); + + /* a thread to tend the pipe */ + threadcreate(openfdthread, nc, STACK); + + /* rewrite as Ropenfd */ + m->rx.type = Ropenfd; + n = GBIT32(m->rpkt); + m->rpkt = erealloc(m->rpkt, n+4); + PBIT32(m->rpkt+n, p[1]); + n += 4; + PBIT32(m->rpkt, n); + m->rpkt[4] = Ropenfd; + m->rx.unixfd = p[1]; + return 0; +} + void connoutthread(void *arg) { @@ -413,6 +609,9 @@ connoutthread(void *arg) io = ioproc(); while((m = recvq(c->outq)) != nil){ err = m->tx.type+1 != m->rx.type; + if(!err && m->isopenfd) + if(xopenfd(m) < 0) + continue; switch(m->tx.type){ case Tflush: om = m->oldm; @@ -446,7 +645,7 @@ connoutthread(void *arg) } if(delhash(m->c->tag, m->ctag, m) == 0) msgput(m); - if(verbose > 1) fprint(2, "%s <- %F\n", c->dir, &m->rx); + if(verbose > 1) fprint(2, "fd#%d <- %F\n", c->fd, &m->rx); rewritehdr(&m->rx, m->rpkt); if(mwrite9p(io, c->fd, m->rpkt) < 0) if(verbose) fprint(2, "write error: %r\n"); @@ -473,6 +672,8 @@ outputthread(void *arg) msgput(m); } closeioproc(io); + fprint(2, "output eof\n"); + threadexitsall(0); } void @@ -483,6 +684,7 @@ inputthread(void *arg) Msg *m; Ioproc *io; + if(verbose) fprint(2, "input thread\n"); io = ioproc(); USED(arg); while((pkt = read9ppkt(io, 0)) != nil){ @@ -514,6 +716,8 @@ inputthread(void *arg) sendq(m->c->outq, m); } closeioproc(io); + fprint(2, "input eof\n"); + threadexitsall(0); } void* @@ -626,15 +830,20 @@ msgput(Msg *m) m->c->nmsg--; m->c = nil; fidput(m->fid); + m->fid = nil; fidput(m->afid); - fidput(m->newfid); - free(m->tpkt); - free(m->rpkt); - m->fid = nil; m->afid = nil; + fidput(m->newfid); m->newfid = nil; + free(m->tpkt); m->tpkt = nil; + free(m->rpkt); m->rpkt = nil; + if(m->rx.type == Ropenfd) + close(m->rx.unixfd); + m->rx.unixfd = -1; + m->isopenfd = 0; + m->internal = 0; m->next = freemsg; freemsg = m; } @@ -649,6 +858,7 @@ msgget(int n) m = msgtab[n]; if(m->ref == 0) return nil; + if(verbose) fprint(2, "msgget %d = %p\n", n, m); m->ref++; return m; } @@ -768,6 +978,12 @@ read9ppkt(Ioproc *io, int fd) free(pkt); return nil; } +/* would do this if we ever got one of these, but we only generate them + if(pkt[4] == Ropenfd){ + newfd = iorecvfd(io, fd); + PBIT32(pkt+n-4, newfd); + } +*/ return pkt; } @@ -795,7 +1011,7 @@ mread9p(Ioproc *io, int fd) int mwrite9p(Ioproc *io, int fd, uchar *pkt) { - int n; + int n, nfd; n = GBIT32(pkt); if(verbose > 2) fprint(2, "write %d %d %.*H\n", fd, n, n, pkt); @@ -803,6 +1019,13 @@ mwrite9p(Ioproc *io, int fd, uchar *pkt) fprint(2, "write error: %r\n"); return -1; } + if(pkt[4] == Ropenfd){ + nfd = GBIT32(pkt+n-4); + if(iosendfd(io, fd, nfd) < 0){ + fprint(2, "send fd error: %r\n"); + return -1; + } + } return 0; } @@ -871,42 +1094,212 @@ rewritehdr(Fcall *f, uchar *pkt) #ifdef _LIB9_H_ /* unix select-based polling */ +struct Ioproc +{ + Channel *c; + Ioproc *next; + int index; +}; + +static struct Ioproc **pio; +static struct pollfd *pfd; +static int npfd; +static struct Ioproc *iofree; + Ioproc* ioproc(void) { - return nil; + Ioproc *io; + + if(iofree == nil){ + pfd = erealloc(pfd, (npfd+1)*sizeof(pfd[0])); + pfd[npfd].events = 0; + pfd[npfd].fd = -1; + iofree = emalloc(sizeof(Ioproc)); + iofree->index = npfd; + iofree->c = chancreate(sizeof(ulong), 1); + pio = erealloc(pio, (npfd+1)*sizeof(pio[0])); + pio[npfd] = iofree; + npfd++; + } + io = iofree; + iofree = io->next; + return io; +} + +void +closeioproc(Ioproc *io) +{ + io->next = iofree; + iofree = io; +} + +void +pollthread(void *v) +{ + int i, n; + + for(;;){ + yield(); + for(i=0; ic, 1); + } + } +} + +static void +noblock(int fd) +{ + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)|O_NONBLOCK); +} + +static void +xwait(Ioproc *io, int fd, int e) +{ + if(verbose) fprint(2, "wait for %d%c\n", fd, e==POLLIN ? 'r' : 'w'); + pfd[io->index].fd = fd; + pfd[io->index].events = e; + recvul(io->c); + if(verbose) fprint(2, "got %d\n", fd); } +static void +rwait(Ioproc *io, int fd) +{ + xwait(io, fd, POLLIN); +} + +static void +wwait(Ioproc *io, int fd) +{ + xwait(io, fd, POLLOUT); +} + long ioread(Ioproc *io, int fd, void *v, long n) { + long r; USED(io); - xxx; + noblock(fd); + while((r=read(fd, v, n)) < 0 && errno == EWOULDBLOCK) + rwait(io, fd); + return r; } long -iowrite(Ioproc *io, int fd, void *v, long n) +ioreadn(Ioproc *io, int fd, void *v, long n) { + long tot, m; + uchar *u; + + u = v; + for(tot=0; totwt-(p)->beg) #define rewind(p) (p)->rd=(p)->beg +#undef create #define create(p) (p)->rd = (p)->wt = (p)->beg #define fsfile(p) (p)->rd = (p)->wt #define truncate(p) (p)->wt = (p)->rd blob - dccd3037022755943512cee76eadb33c3947a592 blob + 8cbf6aac077348accfa714b9d871c472b25009f9 --- src/cmd/dict/dict.c +++ src/cmd/dict/dict.c @@ -59,18 +59,13 @@ void main(int argc, char **argv) { int i, cmd, kflag; - char *line, *p, *root; + char *line, *p; Binit(&binbuf, 0, OREAD); Binit(&boutbuf, 1, OWRITE); kflag = 0; line = 0; dict = 0; - root = getenv("PLAN9"); - if(root == nil) - root = "/usr/local/plan9"; - if(chdir(root) < 0) - sysfatal("chdir %s: %r", root); for(i=0; dicts[i].name; i++){ if(access(dicts[i].path, 0)>=0 && access(dicts[i].indexpath, 0)>=0){ @@ -126,12 +121,12 @@ main(int argc, char **argv) } bdict = Bopen(dict->path, OREAD); if(!bdict) { - err("can't open dictionary %s/%s", root, dict->path); + err("can't open dictionary %s", dict->path); exits("nodict"); } bindex = Bopen(dict->indexpath, OREAD); if(!bindex) { - err("can't open index %s/%s", root, dict->indexpath); + err("can't open index %s", dict->indexpath); exits("noindex"); } indextop = Bseek(bindex, 0L, 2); blob - 8e4db9e9785de8e42622c245fc7d9b9114939a76 blob + 6916d5492f1222c09953fcefd26ae29428602bdf --- src/cmd/dict/utils.c +++ src/cmd/dict/utils.c @@ -5,160 +5,160 @@ Dict dicts[] = { {"oed", "Oxford English Dictionary, 2nd Ed.", - "dict/oed2", "dict/oed2index", + "#9/dict/oed2", "#9/dict/oed2index", oednextoff, oedprintentry, oedprintkey}, {"ahd", "American Heritage Dictionary, 2nd College Ed.", "ahd/DICT.DB", "ahd/index", ahdnextoff, ahdprintentry, ahdprintkey}, {"pgw", "Project Gutenberg Webster Dictionary", - "dict/pgw", "dict/pgwindex", + "#9/dict/pgw", "#9/dict/pgwindex", pgwnextoff, pgwprintentry, pgwprintkey}, {"thesaurus", "Collins Thesaurus", - "dict/thesaurus", "dict/thesindex", + "#9/dict/thesaurus", "#9/dict/thesindex", thesnextoff, thesprintentry, thesprintkey}, {"ce", "Gendai Chinese->English", - "dict/world/sansdata/sandic24.dat", - "dict/world/sansdata/ceindex", + "#9/dict/world/sansdata/sandic24.dat", + "#9/dict/world/sansdata/ceindex", worldnextoff, worldprintentry, worldprintkey}, {"ceh", "Gendai Chinese->English (Hanzi index)", - "dict/world/sansdata/sandic24.dat", - "dict/world/sansdata/cehindex", + "#9/dict/world/sansdata/sandic24.dat", + "#9/dict/world/sansdata/cehindex", worldnextoff, worldprintentry, worldprintkey}, {"ec", "Gendai English->Chinese", - "dict/world/sansdata/sandic24.dat", - "dict/world/sansdata/ecindex", + "#9/dict/world/sansdata/sandic24.dat", + "#9/dict/world/sansdata/ecindex", worldnextoff, worldprintentry, worldprintkey}, {"dae", "Gyldendal Danish->English", - "dict/world/gylddata/sandic30.dat", - "dict/world/gylddata/daeindex", + "#9/dict/world/gylddata/sandic30.dat", + "#9/dict/world/gylddata/daeindex", worldnextoff, worldprintentry, worldprintkey}, {"eda", "Gyldendal English->Danish", - "dict/world/gylddata/sandic29.dat", - "dict/world/gylddata/edaindex", + "#9/dict/world/gylddata/sandic29.dat", + "#9/dict/world/gylddata/edaindex", worldnextoff, worldprintentry, worldprintkey}, {"due", "Wolters-Noordhoff Dutch->English", - "dict/world/woltdata/sandic07.dat", - "dict/world/woltdata/deindex", + "#9/dict/world/woltdata/sandic07.dat", + "#9/dict/world/woltdata/deindex", worldnextoff, worldprintentry, worldprintkey}, {"edu", "Wolters-Noordhoff English->Dutch", - "dict/world/woltdata/sandic06.dat", - "dict/world/woltdata/edindex", + "#9/dict/world/woltdata/sandic06.dat", + "#9/dict/world/woltdata/edindex", worldnextoff, worldprintentry, worldprintkey}, {"fie", "WSOY Finnish->English", - "dict/world/werndata/sandic32.dat", - "dict/world/werndata/fieindex", + "#9/dict/world/werndata/sandic32.dat", + "#9/dict/world/werndata/fieindex", worldnextoff, worldprintentry, worldprintkey}, {"efi", "WSOY English->Finnish", - "dict/world/werndata/sandic31.dat", - "dict/world/werndata/efiindex", + "#9/dict/world/werndata/sandic31.dat", + "#9/dict/world/werndata/efiindex", worldnextoff, worldprintentry, worldprintkey}, {"fe", "Collins French->English", - "dict/fe", "dict/feindex", + "#9/dict/fe", "#9/dict/feindex", pcollnextoff, pcollprintentry, pcollprintkey}, {"ef", "Collins English->French", - "dict/ef", "dict/efindex", + "#9/dict/ef", "#9/dict/efindex", pcollnextoff, pcollprintentry, pcollprintkey}, {"ge", "Collins German->English", - "dict/ge", "dict/geindex", + "#9/dict/ge", "#9/dict/geindex", pcollgnextoff, pcollgprintentry, pcollgprintkey}, {"eg", "Collins English->German", - "dict/eg", "dict/egindex", + "#9/dict/eg", "#9/dict/egindex", pcollgnextoff, pcollgprintentry, pcollgprintkey}, {"ie", "Collins Italian->English", - "dict/ie", "dict/ieindex", + "#9/dict/ie", "#9/dict/ieindex", pcollnextoff, pcollprintentry, pcollprintkey}, {"ei", "Collins English->Italian", - "dict/ei", "dict/eiindex", + "#9/dict/ei", "#9/dict/eiindex", pcollnextoff, pcollprintentry, pcollprintkey}, {"je", "Sanshusha Japanese->English", - "dict/world/sansdata/sandic18.dat", - "dict/world/sansdata/jeindex", + "#9/dict/world/sansdata/sandic18.dat", + "#9/dict/world/sansdata/jeindex", worldnextoff, worldprintentry, worldprintkey}, {"jek", "Sanshusha Japanese->English (Kanji index)", - "dict/world/sansdata/sandic18.dat", - "dict/world/sansdata/jekindex", + "#9/dict/world/sansdata/sandic18.dat", + "#9/dict/world/sansdata/jekindex", worldnextoff, worldprintentry, worldprintkey}, {"ej", "Sanshusha English->Japanese", - "dict/world/sansdata/sandic18.dat", - "dict/world/sansdata/ejindex", + "#9/dict/world/sansdata/sandic18.dat", + "#9/dict/world/sansdata/ejindex", worldnextoff, worldprintentry, worldprintkey}, {"tjeg", "Sanshusha technical Japanese->English,German", - "dict/world/sansdata/sandic16.dat", - "dict/world/sansdata/tjegindex", + "#9/dict/world/sansdata/sandic16.dat", + "#9/dict/world/sansdata/tjegindex", worldnextoff, worldprintentry, worldprintkey}, {"tjegk", "Sanshusha technical Japanese->English,German (Kanji index)", - "dict/world/sansdata/sandic16.dat", - "dict/world/sansdata/tjegkindex", + "#9/dict/world/sansdata/sandic16.dat", + "#9/dict/world/sansdata/tjegkindex", worldnextoff, worldprintentry, worldprintkey}, {"tegj", "Sanshusha technical English->German,Japanese", - "dict/world/sansdata/sandic16.dat", - "dict/world/sansdata/tegjindex", + "#9/dict/world/sansdata/sandic16.dat", + "#9/dict/world/sansdata/tegjindex", worldnextoff, worldprintentry, worldprintkey}, {"tgje", "Sanshusha technical German->Japanese,English", - "dict/world/sansdata/sandic16.dat", - "dict/world/sansdata/tgjeindex", + "#9/dict/world/sansdata/sandic16.dat", + "#9/dict/world/sansdata/tgjeindex", worldnextoff, worldprintentry, worldprintkey}, {"ne", "Kunnskapforlaget Norwegian->English", - "dict/world/kunndata/sandic28.dat", - "dict/world/kunndata/neindex", + "#9/dict/world/kunndata/sandic28.dat", + "#9/dict/world/kunndata/neindex", worldnextoff, worldprintentry, worldprintkey}, {"en", "Kunnskapforlaget English->Norwegian", - "dict/world/kunndata/sandic27.dat", - "dict/world/kunndata/enindex", + "#9/dict/world/kunndata/sandic27.dat", + "#9/dict/world/kunndata/enindex", worldnextoff, worldprintentry, worldprintkey}, {"re", "Leon Ungier Russian->English", - "dict/re", "dict/reindex", + "#9/dict/re", "#9/dict/reindex", simplenextoff, simpleprintentry, simpleprintkey}, {"er", "Leon Ungier English->Russian", - "dict/re", "dict/erindex", + "#9/dict/re", "#9/dict/erindex", simplenextoff, simpleprintentry, simpleprintkey}, {"se", "Collins Spanish->English", - "dict/se", "dict/seindex", + "#9/dict/se", "#9/dict/seindex", pcollnextoff, pcollprintentry, pcollprintkey}, {"es", "Collins English->Spanish", - "dict/es", "dict/esindex", + "#9/dict/es", "#9/dict/esindex", pcollnextoff, pcollprintentry, pcollprintkey}, {"swe", "Esselte Studium Swedish->English", - "dict/world/essedata/sandic34.dat", - "dict/world/essedata/sweindex", + "#9/dict/world/essedata/sandic34.dat", + "#9/dict/world/essedata/sweindex", worldnextoff, worldprintentry, worldprintkey}, {"esw", "Esselte Studium English->Swedish", - "dict/world/essedata/sandic33.dat", - "dict/world/essedata/eswindex", + "#9/dict/world/essedata/sandic33.dat", + "#9/dict/world/essedata/eswindex", worldnextoff, worldprintentry, worldprintkey}, {"movie", "Movies -- by title", - "movie/data", "dict/movtindex", + "movie/data", "#9/dict/movtindex", movienextoff, movieprintentry, movieprintkey}, {"moviea", "Movies -- by actor", - "movie/data", "dict/movaindex", + "movie/data", "#9/dict/movaindex", movienextoff, movieprintentry, movieprintkey}, {"movied", "Movies -- by director", - "movie/data", "dict/movdindex", + "movie/data", "#9/dict/movdindex", movienextoff, movieprintentry, movieprintkey}, {"slang", "English Slang", - "dict/slang", "dict/slangindex", + "#9/dict/slang", "#9/dict/slangindex", slangnextoff, slangprintentry, slangprintkey}, {"robert", "Robert Électronique", - "dict/robert/_pointers", "dict/robert/_index", + "#9/dict/robert/_pointers", "#9/dict/robert/_index", robertnextoff, robertindexentry, robertprintkey}, {"robertv", "Robert Électronique - formes des verbes", - "dict/robert/flex.rob", "dict/robert/_flexindex", + "#9/dict/robert/flex.rob", "#9/dict/robert/_flexindex", robertnextflex, robertflexentry, robertprintkey}, {0, 0, 0, 0, 0} blob - 8450d94bf5833cd02b3a0b0c36ba7c9494d503f7 blob + e2131e777df8a1e39e9d48c05ffa8ac90bc5b489 --- src/cmd/mkfile +++ src/cmd/mkfile @@ -2,11 +2,11 @@ PLAN9=../.. <$PLAN9/src/mkhdr TARG=`ls *.c | sed 's/\.c//'` -LDFLAGS=$LDFLAGS -lthread -lsec -lfs -lmux -lregexp9 -l9 -lbio -lfmt -lutf +LDFLAGS=$LDFLAGS -lthread -lsec -lfs -lmux -lregexp9 -lbio -l9 -lfmt -lutf <$PLAN9/src/mkmany -BUGGERED='CVS|oplumb|plumb|plumb2|mk|vac|9term|venti|htmlfmt' +BUGGERED='CVS|oplumb|plumb2|mk|vac|9term|venti|htmlfmt' DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "$BUGGERED"` <$PLAN9/src/mkdirs blob - 6f95a23a8ab6b9d354f809fe41ca29270e2c510e blob + 912e5ca0235628a823feeca07457db569c03e0b1 --- src/cmd/plumb/fsys.c +++ src/cmd/plumb/fsys.c @@ -3,14 +3,13 @@ #include #include #include -#include #include #include #include "plumber.h" enum { - Stack = 8*1024 + Stack = 32*1024 }; typedef struct Dirtab Dirtab; @@ -73,13 +72,12 @@ struct Holdq struct /* needed because incref() doesn't return value */ { - Lock; - int ref; + Lock lk; + int ref; } rulesref; enum { - DEBUG = 0, NDIR = 50, Nhash = 16, @@ -99,13 +97,10 @@ static Dirtab dir[NDIR] = static int ndir = NQID; static int srvfd; -static int srvclosefd; /* rock for end of pipe to close */ -static int clockfd; static int clock; static Fid *fids[Nhash]; static QLock readlock; static QLock queue; -static char srvfile[128]; static int messagesize = 8192+IOHDRSZ; /* good start */ static void fsysproc(void*); @@ -183,54 +178,35 @@ addport(char *port) static ulong getclock(void) { - char buf[32]; - - seek(clockfd, 0, 0); - read(clockfd, buf, sizeof buf); - return atoi(buf); + return time(0); } void startfsys(void) { - int p[2], fd; + int p[2]; fmtinstall('F', fcallfmt); - clockfd = open("/dev/time", OREAD|OCEXEC); clock = getclock(); if(pipe(p) < 0) error("can't create pipe: %r"); /* 0 will be server end, 1 will be client end */ srvfd = p[0]; - srvclosefd = p[1]; - sprint(srvfile, "/srv/plumb.%s.%d", user, getpid()); - if(putenv("plumbsrv", srvfile) < 0) - error("can't write $plumbsrv: %r"); - fd = create(srvfile, OWRITE|OCEXEC|ORCLOSE, 0600); - if(fd < 0) - error("can't create /srv file: %r"); - if(fprint(fd, "%d", p[1]) <= 0) - error("can't write /srv/file: %r"); - /* leave fd open; ORCLOSE will take care of it */ - - procrfork(fsysproc, nil, Stack, RFFDG); - - close(p[0]); - if(mount(p[1], -1, "/mnt/plumb", MREPL, "") < 0) - error("can't mount /mnt/plumb: %r"); + if(post9pservice(p[1], "plumb") < 0) + sysfatal("post9pservice plumb: %r"); close(p[1]); + proccreate(fsysproc, nil, Stack); } static void -fsysproc(void*) +fsysproc(void *v) { int n; Fcall *t; Fid *f; uchar *buf; - close(srvclosefd); - srvclosefd = -1; + USED(v); t = nil; for(;;){ buf = malloc(messagesize); /* avoid memset of emalloc */ @@ -250,7 +226,7 @@ fsysproc(void*) t = emalloc(sizeof(Fcall)); if(convM2S(buf, n, t) != n) error("convert error in convM2S"); - if(DEBUG) + if(debug) fprint(2, "<= %F\n", t); if(fcall[t->type] == nil) fsysrespond(t, buf, Ebadfcall); @@ -281,7 +257,7 @@ fsysrespond(Fcall *t, uchar *buf, char *err) error("convert error in convS2M"); if(write(srvfd, buf, n) != n) error("write error in respond"); - if(DEBUG) + if(debug) fprint(2, "=> %F\n", t); free(buf); } @@ -555,8 +531,10 @@ dispose(Fcall *t, uchar *buf, Plumbmsg *m, Ruleset *rs } static Fcall* -fsysversion(Fcall *t, uchar *buf, Fid*) +fsysversion(Fcall *t, uchar *buf, Fid *fid) { + USED(fid); + if(t->msize < 256){ fsysrespond(t, buf, "version: message size too small"); return t; @@ -574,8 +552,9 @@ fsysversion(Fcall *t, uchar *buf, Fid*) } static Fcall* -fsysauth(Fcall *t, uchar *buf, Fid*) +fsysauth(Fcall *t, uchar *buf, Fid *fid) { + USED(fid); fsysrespond(t, buf, "plumber: authentication not required"); return t; } @@ -605,10 +584,11 @@ fsysattach(Fcall *t, uchar *buf, Fid *f) } static Fcall* -fsysflush(Fcall *t, uchar *buf, Fid*) +fsysflush(Fcall *t, uchar *buf, Fid *fid) { int i; + USED(fid); qlock(&queue); for(i=NQID; ioldtag); @@ -729,14 +709,14 @@ fsysopen(Fcall *t, uchar *buf, Fid *f) if(((f->dir->perm&~(DMDIR|DMAPPEND))&m) != m) goto Deny; if(f->qid.path==Qrules && (mode==OWRITE || mode==ORDWR)){ - lock(&rulesref); + lock(&rulesref.lk); if(rulesref.ref++ != 0){ rulesref.ref--; - unlock(&rulesref); + unlock(&rulesref.lk); fsysrespond(t, buf, Einuse); return t; } - unlock(&rulesref); + unlock(&rulesref.lk); } if(clearrules){ writerules(nil, 0); @@ -761,8 +741,9 @@ fsysopen(Fcall *t, uchar *buf, Fid *f) } static Fcall* -fsyscreate(Fcall *t, uchar *buf, Fid*) +fsyscreate(Fcall *t, uchar *buf, Fid *fid) { + USED(fid); fsysrespond(t, buf, Eperm); return t; } @@ -916,15 +897,17 @@ fsysstat(Fcall *t, uchar *buf, Fid *f) } static Fcall* -fsyswstat(Fcall *t, uchar *buf, Fid*) +fsyswstat(Fcall *t, uchar *buf, Fid *fid) { + USED(fid); fsysrespond(t, buf, Eperm); return t; } static Fcall* -fsysremove(Fcall *t, uchar *buf, Fid*) +fsysremove(Fcall *t, uchar *buf, Fid *fid) { + USED(fid); fsysrespond(t, buf, Eperm); return t; } @@ -945,9 +928,9 @@ fsysclunk(Fcall *t, uchar *buf, Fid *f) * unless last write ended with a blank line */ writerules(nil, 0); - lock(&rulesref); + lock(&rulesref.lk); rulesref.ref--; - unlock(&rulesref); + unlock(&rulesref.lk); } prev = nil; for(p=d->fopen; p; p=p->nextopen){ blob - 42a9232ff77a245681a9e294e09e2f18de8a7504 blob + dc1abbb1554cbb6eabbab288eaa7eb2286e491e0 --- src/cmd/plumb/match.c +++ src/cmd/plumb/match.c @@ -6,6 +6,7 @@ #include #include "plumber.h" +/* static char* nonnil(char *s) { @@ -13,6 +14,7 @@ nonnil(char *s) return ""; return s; } +*/ int verbis(int obj, Plumbmsg *m, Rule *r) @@ -44,10 +46,10 @@ setvar(Resub rs[10], char *match[10]) free(match[i]); match[i] = nil; } - for(i=0; i<10 && rs[i].sp!=nil; i++){ - n = rs[i].ep-rs[i].sp; + for(i=0; i<10 && rs[i].s.sp!=nil; i++){ + n = rs[i].e.ep-rs[i].s.sp; match[i] = emalloc(n+1); - memmove(match[i], rs[i].sp, n); + memmove(match[i], rs[i].s.sp, n); match[i][n] = '\0'; } } @@ -66,7 +68,7 @@ clickmatch(Reprog *re, char *text, Resub rs[10], int c for(i=0; i<=click; i++){ memset(rs, 0, 10*sizeof(Resub)); if(regexec(re, text+i, rs, 10)) - if(rs[0].sp<=clickp && clickp<=rs[0].ep) + if(rs[0].s.sp<=clickp && clickp<=rs[0].e.ep) return 1; } return 0; @@ -94,8 +96,8 @@ verbmatches(int obj, Plumbmsg *m, Rule *r, Exec *e) } if(!clickmatch(r->regex, m->data, rs, atoi(clickval))) break; - p0 = rs[0].sp - m->data; - p1 = rs[0].ep - m->data; + p0 = rs[0].s.sp - m->data; + p1 = rs[0].e.ep - m->data; if(e->p0 >=0 && !(p0==e->p0 && p1==e->p1)) break; e->clearclick = 1; @@ -120,7 +122,7 @@ verbmatches(int obj, Plumbmsg *m, Rule *r, Exec *e) /* must match full text */ if(ntext < 0) ntext = strlen(alltext); - if(!regexec(r->regex, alltext, rs, 10) || rs[0].sp!=alltext || rs[0].ep!=alltext+ntext) + if(!regexec(r->regex, alltext, rs, 10) || rs[0].s.sp!=alltext || rs[0].e.ep!=alltext+ntext) break; setvar(rs, e->match); return 1; @@ -389,7 +391,7 @@ enum { NARGS = 100, NARGCHAR = 8*1024, - EXECSTACK = 4096+(NARGS+1)*sizeof(char*)+NARGCHAR + EXECSTACK = 32*1024+(NARGS+1)*sizeof(char*)+NARGCHAR }; /* copy argv to stack and free the incoming strings, so we don't leak argument vectors */ @@ -419,19 +421,17 @@ stackargv(char **inargv, char *argv[NARGS+1], char arg void execproc(void *v) { + int fd[3]; char **av; - char buf[1024], *args[NARGS+1], argc[NARGCHAR]; + char *args[NARGS+1], argc[NARGCHAR]; - rfork(RFFDG); - close(0); - open("/dev/null", OREAD); + fd[0] = open("/dev/null", OREAD); + fd[1] = dup(1, -1); + fd[2] = dup(2, -1); av = v; stackargv(av, args, argc); free(av); - procexec(nil, args[0], args); - if(args[0][0]!='/' && strncmp(args[0], "./", 2)!=0 && strncmp(args[0], "../", 3)!=0) - snprint(buf, sizeof buf, "/bin/%s", args[0]); - procexec(nil, buf, args); + procexec(nil, fd, args[0], args); threadexits("can't exec"); } blob - d6a146541af7fba17ccb02ce4329d7bcd78ea783 blob + 6550387f85461e005767459d452ab22f892c9d82 --- src/cmd/plumb/mkfile +++ src/cmd/plumb/mkfile @@ -1,11 +1,10 @@ -syms - 8c -aa fsys.c match.c rules.c >>syms +LDFLAGS=$LDFLAGS -lplumb -lfs -lmux -lthread -lregexp9 -l9 -lbio -lfmt -lutf blob - d0bd9c14e33ed9cadeeefc12c3ac6cd5573d1bc1 blob + 424469f2d2ee2405dfbc1e8a71b0a388d5a785bb --- src/cmd/plumb/plumber.c +++ src/cmd/plumb/plumber.c @@ -3,10 +3,10 @@ #include #include #include -#include #include #include "plumber.h" +int debug; char *plumbfile; char *user; char *home; @@ -47,13 +47,18 @@ threadmain(int argc, char *argv[]) progname = "plumber"; ARGBEGIN{ + case 'd': + debug = 1; + break; case 'p': plumbfile = ARGF(); break; }ARGEND - user = getenv("user"); + user = getuser(); home = getenv("home"); + if(home == nil) + home = getenv("HOME"); if(user==nil || home==nil) error("can't initialize $user or $home: %r"); if(plumbfile == nil){ blob - 0d1205f988acdf04ae3d7e1ed02b176948ad500d blob + 4b9267a5fdc6e88a02df6a08a8a8b4144d3d7572 --- src/cmd/plumb/plumber.h +++ src/cmd/plumb/plumber.h @@ -91,3 +91,4 @@ jmp_buf parsejmp; char *lasterror; char **ports; int nports; +int debug; blob - 262f6d67f53928c16aeccc2964e46cc974dc3fbe blob + b51bb61f013721a49727787ab58810b3c5d88594 --- src/cmd/plumb/rules.c +++ src/cmd/plumb/rules.c @@ -143,7 +143,7 @@ char* getline(void) { static int n = 0; - static char *s, *incl; + static char *s /*, *incl*/; int c, i; i = 0; @@ -414,7 +414,7 @@ include(char *s) t = args[1]; fd = open(t, OREAD); if(fd<0 && t[0]!='/' && strncmp(t, "./", 2)!=0 && strncmp(t, "../", 3)!=0){ - snprint(buf, sizeof buf, "/sys/lib/plumb/%s", t); + snprint(buf, sizeof buf, "#9/plumb/%s", t); t = buf; fd = open(t, OREAD); } blob - 1b250ba1143f27c911cda5237b0dec98887fffb0 blob + abb66cc387c221526b83a496130ad3f44f53ed38 --- src/cmd/rc/plan9ish.c +++ src/cmd/rc/plan9ish.c @@ -27,6 +27,8 @@ char *syssigname[]={ char* Rcmain(void) { + return "#9/rcmain"; +/* static char buf[256]; char *root; @@ -35,9 +37,10 @@ Rcmain(void) root = "/usr/local/plan9"; snprint(buf, sizeof buf, "%s/rcmain", root); return buf; +*/ } -char Fdprefix[]="/dev/fd/"; +char Fdprefix[]="#d/"; void execfinit(void); void execbind(void); void execmount(void); blob - 45cfc3bcaf7d66e6f6414137653ab58e04ef26ca blob + b8a67b9024ef885d38516e04c370130a801834d2 --- src/cmd/sam/unix.c +++ src/cmd/sam/unix.c @@ -212,94 +212,6 @@ erealloc(void *p, ulong n) if(p == 0) panic("realloc fails"); return p; -} - -#if 0 -char * -strdup(const char *s) -{ - return strcpy(emalloc(strlen(s)), s); -} -#endif - -/* -void exits(const char *s) -{ - if (s) fprint(2, "exit: %s\n", s); - exit(s != 0); -} - -void -_exits(const char *s) -{ - if (s) fprint(2, "exit: %s\n", s); - _exit(s != 0); -} - -int errstr(char *buf, int size) -{ - extern int errno; - - snprint(buf, size, "%s", strerror(errno)); - return 1; -} -*/ - -int -create(char *name, int omode, ulong perm) -{ - int mode; - int fd; - - if (omode & OWRITE) mode = O_WRONLY; - else if (omode & OREAD) mode = O_RDONLY; - else mode = O_RDWR; - - if ((fd = open(name, mode|O_CREAT|O_TRUNC, perm)) < 0) - return fd; - - if (omode & OCEXEC) - fcntl(fd, F_SETFD, fcntl(fd,F_GETFD,0) | FD_CLOEXEC); - - /* SES - not exactly right, but hopefully good enough. */ - if (omode & ORCLOSE) - remove(name); - - return fd; } -/* SHOULD BE ELSEWHERE */ -#if 0 /* needed on old __APPLE__ */ -#include -Lock plk; - -ulong -pread(int fd, void *buf, ulong n, ulong off) -{ - ulong rv; - - lock(&plk); - if (lseek(fd, off, 0) != off) - return -1; - rv = read(fd, buf, n); - unlock(&plk); - - return rv; -} - -ulong -pwrite(int fd, void *buf, ulong n, ulong off) -{ - ulong rv; - - lock(&plk); - if (lseek(fd, off, 0) != off) - return -1; - rv = write(fd, buf, n); - unlock(&plk); - - return rv; -} -#endif - blob - 05e9d5891d7fa3ef644fc88c7e9a60ce8d472120 blob + d9e307619d24cd90cf733442c03487d6f657867b --- src/cmd/yacc.c +++ src/cmd/yacc.c @@ -13,8 +13,8 @@ #define SETBIT(a,i) ((a)[(i)>>5] |= (1<<((i)&037))) #define NWORDS(n) (((n)+32)/32) -#define PARSER "lib/yaccpar" -#define PARSERS "lib/yaccpars" +#define PARSER "#9/lib/yaccpar" +#define PARSERS "#9/lib/yaccpars" #define TEMPNAME "y.tmp.XXXXXX" #define ACTNAME "y.acts.XXXXXX" #define OFILE "tab.c" @@ -398,19 +398,10 @@ void others(void) { int c, i, j; - char *s, *root; - root = getenv("PLAN9"); - if(root == nil) - root = "/usr/local/plan9"; - s = malloc(strlen(root)+1+strlen(parser)+1); - strcpy(s, root); - strcat(s, "/"); - strcat(s, parser); - finput = Bopen(s, OREAD); + finput = Bopen(parser, OREAD); if(finput == 0) - error("cannot find parser %s", s); - free(s); + error("cannot find parser %s", parser); warray("yyr1", levprd, nprod); aryfil(temp1, nprod, 0); PLOOP(1, i) blob - 04c712d9b27b96457928dfe0f9836cd075ffec51 blob + 9f07bd2293c96907db947cf5003832c035491786 --- src/lib9/announce.c +++ src/lib9/announce.c @@ -5,13 +5,14 @@ #include #include #include +#include #undef sun #define sun sockun extern int _p9dialparse(char*, char**, char**, u32int*, int*); -static int -getfd(char *dir) +int +_p9netfd(char *dir) { int fd; @@ -83,7 +84,6 @@ p9announce(char *addr, char *dir) if(proto == SOCK_STREAM){ listen(s, 8); putfd(dir, s); -print("announce dir: %s\n", dir); } return s; @@ -95,9 +95,21 @@ Unix: return -1; sn = sizeof sun; if(bind(s, (struct sockaddr*)&sun, sizeof sun) < 0){ + if(errno == EADDRINUSE + && connect(s, (struct sockaddr*)&sun, sizeof sun) < 0 + && errno == ECONNREFUSED){ + /* dead socket, so remove it */ + remove(unix); + close(s); + if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + return -1; + if(bind(s, (struct sockaddr*)&sun, sizeof sun) >= 0) + goto Success; + } close(s); return -1; } +Success: listen(s, 8); putfd(dir, s); return s; @@ -108,18 +120,15 @@ p9listen(char *dir, char *newdir) { int fd; - if((fd = getfd(dir)) < 0){ + if((fd = _p9netfd(dir)) < 0){ werrstr("bad 'directory' in listen: %s", dir); return -1; } -print("accept %d", fd); if((fd = accept(fd, nil, nil)) < 0) return -1; -print(" -> %d\n", fd); putfd(newdir, fd); -print("listen dir: %s\n", newdir); return fd; } @@ -128,7 +137,7 @@ p9accept(int cfd, char *dir) { int fd; - if((fd = getfd(dir)) < 0){ + if((fd = _p9netfd(dir)) < 0){ werrstr("bad 'directory' in accept"); return -1; } blob - 89c695ae172305087ae1801140ee1b19ff13f080 blob + 5f2d58bad578f09233321a9f0b30f42cc650d067 --- src/lib9/await.c +++ src/lib9/await.c @@ -45,6 +45,7 @@ static struct { #endif SIGUSR1, "sys: usr1", SIGUSR2, "sys: usr2", + SIGPIPE, "sys: write on closed pipe", }; char* blob - fcdcd42d60f6f0d533747aab47b01af7651cf926 blob + 920775ea12606a6f99ea8adf3823349d454cc009 --- src/lib9/convM2S.c +++ src/lib9/convM2S.c @@ -138,6 +138,7 @@ convM2S(uchar *ap, uint nap, Fcall *f) break; case Topen: + case Topenfd: if(p+BIT32SZ+BIT8SZ > ep) return 0; f->fid = GBIT32(p); @@ -260,6 +261,7 @@ convM2S(uchar *ap, uint nap, Fcall *f) break; case Ropen: + case Ropenfd: case Rcreate: p = gqid(p, ep, &f->qid); if(p == nil) @@ -268,6 +270,12 @@ convM2S(uchar *ap, uint nap, Fcall *f) return 0; f->iounit = GBIT32(p); p += BIT32SZ; + if(f->type == Ropenfd){ + if(p+BIT32SZ > ep) + return 0; + f->unixfd = GBIT32(p); + p += BIT32SZ; + } break; case Rread: blob - 9acdcfa567fbb744c66980c00bea5397ad895f98 blob + 6e9d2719270832bb2d985b0475197eacc8939290 --- src/lib9/convS2M.c +++ src/lib9/convS2M.c @@ -92,6 +92,7 @@ sizeS2M(Fcall *f) break; case Topen: + case Topenfd: n += BIT32SZ; n += BIT8SZ; break; @@ -164,6 +165,12 @@ sizeS2M(Fcall *f) n += BIT32SZ; break; + case Ropenfd: + n += QIDSZ; + n += BIT32SZ; + n += BIT32SZ; + break; + case Rread: n += BIT32SZ; n += f->count; @@ -257,6 +264,7 @@ convS2M(Fcall *f, uchar *ap, uint nap) break; case Topen: + case Topenfd: PBIT32(p, f->fid); p += BIT32SZ; PBIT8(p, f->mode); @@ -347,9 +355,14 @@ convS2M(Fcall *f, uchar *ap, uint nap) case Ropen: case Rcreate: + case Ropenfd: p = pqid(p, &f->qid); PBIT32(p, f->iounit); p += BIT32SZ; + if(f->type == Ropenfd){ + PBIT32(p, f->unixfd); + p += BIT32SZ; + } break; case Rread: blob - abef0c3515d2456d073ff03f3eaacde7f161532e blob + bdad5f6a0c8f8e69a6b0f594255deb43adc6ccf7 --- src/lib9/create.c +++ src/lib9/create.c @@ -1,8 +1,54 @@ #include +#define NOPLAN9DEFINES #include +#include +extern char *_p9translate(char*); + int -create(char *path, int mode, ulong perm) +p9create(char *xpath, int mode, ulong perm) { - return open(path, mode|O_CREAT|O_TRUNC, perm); + int fd, cexec, umode, rclose; + char *path; + + if((path = _p9translate(xpath)) == nil) + return -1; + + cexec = mode&OCEXEC; + rclose = mode&ORCLOSE; + mode &= ~(ORCLOSE|OCEXEC); + + /* XXX should get mode mask right? */ + fd = -1; + if(perm&DMDIR){ + if(mode != OREAD){ + werrstr("bad mode in directory create"); + goto out; + } + if(mkdir(path, perm&0777) < 0) + goto out; + fd = open(path, O_RDONLY); + }else{ + umode = (mode&3)|O_CREAT|O_TRUNC; + mode &= ~(3|OTRUNC); + if(mode&OEXCL){ + umode |= O_EXCL; + mode &= ~OEXCL; + } + if(mode){ + werrstr("unsupported mode in create"); + goto out; + } + fd = open(path, umode, perm); + } +out: + if(fd >= 0){ + if(cexec) + fcntl(fd, F_SETFL, FD_CLOEXEC); + if(rclose) + remove(path); + } + if(path != xpath) + free(path); + return fd; } blob - 4eef88dece82b5c102c1a4deb66119bfaff3e2a3 blob + 592316fe7db49a1445e66472a547e79df7448c3a --- src/lib9/fcallfmt.c +++ src/lib9/fcallfmt.c @@ -74,9 +74,16 @@ fcallfmt(Fmt *fmt) seprint(buf, e, "Topen tag %ud fid %ud mode %d", tag, fid, f->mode); break; case Ropen: - seprint(buf, e, "Ropen tag %ud qid " QIDFMT " iounit %ud ", tag, + seprint(buf, e, "Ropen tag %ud qid " QIDFMT " iounit %ud", tag, f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit); break; + case Topenfd: /* 98 */ + seprint(buf, e, "Topenfd tag %ud fid %ud mode %d", tag, fid, f->mode); + break; + case Ropenfd: + seprint(buf, e, "Ropenfd tag %ud qid " QIDFMT " iounit %ud unixfd %d", tag, + f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit, f->unixfd); + break; case Tcreate: /* 114 */ seprint(buf, e, "Tcreate tag %ud fid %ud name %s perm %M mode %d", tag, fid, f->name, (ulong)f->perm, f->mode); break; blob - c6ff71605ee17216a5d8b68a00c1d3541c53610f blob + 2a2d1391338543560e7cb5209cfa0016dc0c26b2 --- src/lib9/getenv.c +++ src/lib9/getenv.c @@ -13,3 +13,15 @@ p9getenv(char *s) return strdup(t); } +int +p9putenv(char *s, char *v) +{ + char *t; + + t = smprint("%s=%s", s, v); + if(t == nil) + return -1; + putenv(t); + free(t); + return 0; +} blob - 14d8c0e080846b16b1a2c6870df2eec872cfb99d blob + a0e75fc36fa1a31463a56aba4f7c2070ca97e24b --- src/lib9/mkfile +++ src/lib9/mkfile @@ -8,6 +8,8 @@ OFILES=\ _p9dialparse.$O\ _p9dir.$O\ _p9proc.$O\ + _p9translate.$O\ + access.$O\ announce.$O\ argv0.$O\ atexit.$O\ @@ -40,11 +42,13 @@ OFILES=\ getcallerpc-$OBJTYPE.$O\ getenv.$O\ getfields.$O\ + getns.$O\ getuser.$O\ getwd.$O\ jmp.$O\ lock.$O\ main.$O\ + malloc.$O\ malloctag.$O\ mallocz.$O\ nan.$O\ @@ -53,13 +57,18 @@ OFILES=\ notify.$O\ nrand.$O\ nulldir.$O\ + open.$O\ + pipe.$O\ + post9p.$O\ postnote.$O\ qlock.$O\ quote.$O\ + read9pmsg.$O\ readn.$O\ rendez-$SYSNAME.$O\ rfork.$O\ seek.$O\ + sendfd.$O\ sleep.$O\ strecpy.$O\ sysfatal.$O\ blob - 460eabfe40a1407a1cf68ac3c00879cf7f7c0532 blob + 160755d0b91ba317d7f5585acc8f94be22da492a --- src/lib9/notify.c +++ src/lib9/notify.c @@ -19,7 +19,7 @@ static int sigs[] = { #endif SIGFPE, SIGBUS, - SIGSEGV, +/* SIGSEGV, */ SIGSYS, SIGPIPE, SIGALRM, blob - 270c3cddf04043ca3151ea2bccf28094132b0cca blob + f3a21928dd0278596dc931e5cd69f8727cb82758 --- src/lib9/rfork.c +++ src/lib9/rfork.c @@ -9,7 +9,7 @@ p9rfork(int flags) if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){ /* check other flags before we commit */ flags &= ~(RFPROC|RFFDG); - if(flags & ~(RFNOTEG)){ + if(flags & ~(RFNOTEG|RFNAMEG)){ werrstr("unknown flags %08ux in rfork", flags); return -1; } @@ -17,11 +17,14 @@ p9rfork(int flags) if(pid != 0) return pid; } - if(flags&RFPROC){ - werrstr("cannot use rfork to fork -- use ffork"); + werrstr("cannot use rfork for shared memory -- use ffork"); return -1; } + if(flags&RFNAMEG){ + /* XXX set $NAMESPACE to a new directory */ + flags &= ~RFNAMEG; + } if(flags&RFNOTEG){ setpgid(0, getpid()); flags &= ~RFNOTEG; blob - a1ff278af9f2da9a6613a262f607e780d7a749ea blob + 0b3dc253a836db332ecb2d7268f20375f5bfb8f2 --- src/libdraw/openfont.c +++ src/libdraw/openfont.c @@ -9,21 +9,15 @@ openfont(Display *d, char *name) { Font *fnt; int fd, i, n; - char *buf, *nambuf, *root; + char *buf, *nambuf; nambuf = 0; fd = open(name, OREAD); if(fd < 0 && strncmp(name, "/lib/font/bit/", 14) == 0){ - root = getenv("PLAN9"); - if(root == nil) - return 0; - nambuf = malloc(strlen(root)+5+strlen(name+13)+1); + nambuf = smprint("#9/font/%s", name+14); if(nambuf == nil) return 0; - strcpy(nambuf, root); - strcat(nambuf, "/font"); - strcat(nambuf, name+13); if((fd = open(nambuf, OREAD)) < 0){ free(nambuf); return 0; blob - 458efc61fdee4de8974315802a1ecd8d0fc6a274 blob + 9a6585cbc7a745226798e17d0bd4098a433c9300 --- src/libdraw/x11-alloc.c +++ src/libdraw/x11-alloc.c @@ -10,7 +10,7 @@ * Allocate a Memimage with an optional pixmap backing on the X server. */ Memimage* -xallocmemimage(Rectangle r, u32int chan, int pixmap) +_xallocmemimage(Rectangle r, u32int chan, int pixmap) { int d, offset; Memimage *m; @@ -95,7 +95,7 @@ xallocmemimage(Rectangle r, u32int chan, int pixmap) Memimage* allocmemimage(Rectangle r, u32int chan) { - return xallocmemimage(r, chan, PMundef); + return _xallocmemimage(r, chan, PMundef); } void blob - 25a325c62a620e81793a140fff542176f01b04b5 blob + 7a84a98372349917c3102caad717f84270423b52 --- src/libdraw/x11-cload.c +++ src/libdraw/x11-cload.c @@ -13,7 +13,7 @@ cloadmemimage(Memimage *i, Rectangle r, uchar *data, i n = _cloadmemimage(i, r, data, ndata); if(n > 0 && i->X) - xputxdata(i, r); + _xputxdata(i, r); return n; } blob - 97438740e899e297802ca550fcf6ef45aa59e4aa blob + 6373e4e3a537da13ea99a3ad9e2dc87454b7bfb9 --- src/libdraw/x11-draw.c +++ src/libdraw/x11-draw.c @@ -24,11 +24,11 @@ memimagedraw(Memimage *dst, Rectangle r, Memimage *src /* only fetch dst data if we need it */ if((par->state&(Simplemask|Fullmask)) != (Simplemask|Fullmask)) - xgetxdata(dst, par->r); + _xgetxdata(dst, par->r); /* always fetch source and mask */ - xgetxdata(src, par->sr); - xgetxdata(mask, par->mr); + _xgetxdata(src, par->sr); + _xgetxdata(mask, par->mr); /* now can run memimagedraw on the in-memory bits */ _memimagedraw(par); @@ -37,7 +37,7 @@ memimagedraw(Memimage *dst, Rectangle r, Memimage *src return; /* put bits back on x server */ - xputxdata(dst, par->r); + _xputxdata(dst, par->r); } static int @@ -66,7 +66,7 @@ xdraw(Memdrawparam *par) */ m = Simplesrc|Simplemask|Fullmask; if((state&m) == m){ - xfillcolor(dst, r, par->sdval); + _xfillcolor(dst, r, par->sdval); // xdirtyxdata(dst, r); return 1; } blob - 408eb4191aba4f1c8d5f257e4bb49d95b407eab6 blob + ba9d031b6914ca710cf29fb432a232c260cec238 --- src/libdraw/x11-event.c +++ src/libdraw/x11-event.c @@ -48,7 +48,7 @@ eread(ulong keys, Event *e) xmask |= MouseMask|StructureNotifyMask; if(keys&Ekeyboard){ xmask |= KeyPressMask; - if((r = xtoplan9kbd(nil)) >= 0){ + if((r = _xtoplan9kbd(nil)) >= 0){ e->kbdc = r; return Ekeyboard; } @@ -60,24 +60,24 @@ again: switch(xevent.type){ case Expose: - xexpose(&xevent, _x.display); + _xexpose(&xevent, _x.display); goto again; case DestroyNotify: - if(xdestroy(&xevent, _x.display)) + if(_xdestroy(&xevent, _x.display)) postnote(PNGROUP, getpgrp(), "hangup"); goto again; case ConfigureNotify: - if(xconfigure(&xevent, _x.display)) + if(_xconfigure(&xevent, _x.display)) eresized(1); goto again; case ButtonPress: case ButtonRelease: case MotionNotify: - if(xtoplan9mouse(_x.display, &xevent, &e->mouse) < 0) + if(_xtoplan9mouse(_x.display, &xevent, &e->mouse) < 0) goto again; return Emouse; case KeyPress: - e->kbdc = xtoplan9kbd(&xevent); + e->kbdc = _xtoplan9kbd(&xevent); if(e->kbdc == -1) goto again; return Ekeyboard; @@ -136,7 +136,7 @@ ecanmouse(void) eflush(); again: if(XCheckWindowEvent(_x.display, _x.drawable, MouseMask, &xe)){ - if(xtoplan9mouse(_x.display, &xe, &m) < 0) + if(_xtoplan9mouse(_x.display, &xe, &m) < 0) goto again; XPutBackEvent(_x.display, &xe); return 1; @@ -151,13 +151,13 @@ ecankbd(void) int r; eflush(); - if((r = xtoplan9kbd(nil)) >= 0){ - xtoplan9kbd((XEvent*)-1); + if((r = _xtoplan9kbd(nil)) >= 0){ + _xtoplan9kbd((XEvent*)-1); return 1; } again: if(XCheckWindowEvent(_x.display, _x.drawable, KeyPressMask, &xe)){ - if(xtoplan9kbd(&xe) == -1) + if(_xtoplan9kbd(&xe) == -1) goto again; XPutBackEvent(_x.display, &xe); return 1; @@ -168,12 +168,12 @@ again: void emoveto(Point p) { - xmoveto(p); + _xmoveto(p); } void esetcursor(Cursor *c) { - xsetcursor(c); + _xsetcursor(c); } blob - ff0b2e86527813a32cc37367cbf08b71c2f43600 blob + 33fc6a2ad145cb730ca027728242291c77240174 --- src/libdraw/x11-fill.c +++ src/libdraw/x11-fill.c @@ -13,13 +13,13 @@ memfillcolor(Memimage *m, u32int val) if(m->X == nil) return; if((val & 0xFF) == 0xFF) /* full alpha */ - xfillcolor(m, m->r, _rgbatoimg(m, val)); + _xfillcolor(m, m->r, _rgbatoimg(m, val)); else - xputxdata(m, m->r); + _xputxdata(m, m->r); } void -xfillcolor(Memimage *m, Rectangle r, u32int v) +_xfillcolor(Memimage *m, Rectangle r, u32int v) { Point p; Xmem *xm; blob - a6d4b12ecc727f9c608327bc3dfb26c37433a6bd blob + 693b2938deb86e4388dd6611c38a3d49ad831da0 --- src/libdraw/x11-get.c +++ src/libdraw/x11-get.c @@ -16,7 +16,7 @@ addrect(Rectangle *rp, Rectangle r) } XImage* -xgetxdata(Memimage *m, Rectangle r) +_xgetxdata(Memimage *m, Rectangle r) { int x, y; uchar *p; @@ -55,7 +55,7 @@ xgetxdata(Memimage *m, Rectangle r) } void -xputxdata(Memimage *m, Rectangle r) +_xputxdata(Memimage *m, Rectangle r) { int offset, x, y; uchar *p; @@ -97,7 +97,7 @@ xputxdata(Memimage *m, Rectangle r) } void -xdirtyxdata(Memimage *m, Rectangle r) +_xdirtyxdata(Memimage *m, Rectangle r) { Xmem *xm; blob - 6f87b41241a6ba1e1324dbb40a3dfdabf7a614d4 blob + fb6a91449fbfb31e090eb0b1dfd2eda2d6dac777 --- src/libdraw/x11-init.c +++ src/libdraw/x11-init.c @@ -359,7 +359,7 @@ xattach(char *label) _x.screenr = r; _x.screenpm = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth); _x.nextscreenpm = _x.screenpm; - _x.screenimage = xallocmemimage(r, _x.chan, _x.screenpm); + _x.screenimage = _xallocmemimage(r, _x.chan, _x.screenpm); /* * Allocate some useful graphics contexts for the future. @@ -651,7 +651,7 @@ flushmemscreen(Rectangle r) } void -xexpose(XEvent *e, XDisplay *xd) +_xexpose(XEvent *e, XDisplay *xd) { XExposeEvent *xe; Rectangle r; @@ -673,7 +673,7 @@ xexpose(XEvent *e, XDisplay *xd) } int -xdestroy(XEvent *e, XDisplay *xd) +_xdestroy(XEvent *e, XDisplay *xd) { XDestroyWindowEvent *xe; @@ -686,7 +686,7 @@ xdestroy(XEvent *e, XDisplay *xd) } int -xconfigure(XEvent *e, XDisplay *xd) +_xconfigure(XEvent *e, XDisplay *xd) { Rectangle r; XConfigureEvent *xe = (XConfigureEvent*)e; @@ -719,7 +719,7 @@ xreplacescreenimage(void) return 0; pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth); - m = xallocmemimage(r, _x.chan, pixmap); + m = _xallocmemimage(r, _x.chan, pixmap); if(_x.nextscreenpm != _x.screenpm) XFreePixmap(_x.display, _x.nextscreenpm); _x.nextscreenpm = pixmap; blob - 0c9924499c38d1708611fe582620a6de315af31d blob + 8e72b011e66d53e9ea0a2a29a7d27f70adea3384 --- src/libdraw/x11-itrans.c +++ src/libdraw/x11-itrans.c @@ -12,7 +12,7 @@ #include "x11-memdraw.h" static int -_xtoplan9kbd(XEvent *e) +__xtoplan9kbd(XEvent *e) { int ind, k, md; @@ -125,7 +125,7 @@ xtoplan9latin1(XEvent *e) int n; int r; - r = _xtoplan9kbd(e); + r = __xtoplan9kbd(e); if(r < 0) return nil; if(alting){ @@ -156,7 +156,7 @@ xtoplan9latin1(XEvent *e) } int -xtoplan9kbd(XEvent *e) +_xtoplan9kbd(XEvent *e) { static Rune *r; @@ -173,7 +173,7 @@ xtoplan9kbd(XEvent *e) } int -xtoplan9mouse(XDisplay *xd, XEvent *e, Mouse *m) +_xtoplan9mouse(XDisplay *xd, XEvent *e, Mouse *m) { int s; XButtonEvent *be; @@ -260,7 +260,7 @@ xtoplan9mouse(XDisplay *xd, XEvent *e, Mouse *m) } void -xmoveto(Point p) +_xmoveto(Point p) { XWarpPointer(_x.display, None, _x.drawable, 0, 0, 0, 0, p.x, p.y); XFlush(_x.display); @@ -296,7 +296,7 @@ xcursorarrow(void) void -xsetcursor(Cursor *c) +_xsetcursor(Cursor *c) { XColor fg, bg; XCursor xc; @@ -335,7 +335,7 @@ struct { } clip; char* -xgetsnarf(XDisplay *xd) +_xgetsnarf(XDisplay *xd) { uchar *data, *xdata; Atom clipboard, type, prop; @@ -420,7 +420,7 @@ out: } void -xputsnarf(XDisplay *xd, char *data) +_xputsnarf(XDisplay *xd, char *data) { XButtonEvent e; @@ -445,7 +445,7 @@ xputsnarf(XDisplay *xd, char *data) } int -xselect(XEvent *e, XDisplay *xd) +_xselect(XEvent *e, XDisplay *xd) { char *name; XEvent r; @@ -493,12 +493,12 @@ if(0) fprint(2, "xselect target=%d requestor=%d proper void putsnarf(char *data) { - xputsnarf(_x.snarfcon, data); + _xputsnarf(_x.snarfcon, data); } char* getsnarf(void) { - return xgetsnarf(_x.snarfcon); + return _xgetsnarf(_x.snarfcon); } blob - 443074e994b4c4c3aa1bda37854f6465bd26d297 blob + 676027e306e4a39cdabadc9358c5a9d2f010eb1b --- src/libdraw/x11-keyboard.c +++ src/libdraw/x11-keyboard.c @@ -46,12 +46,12 @@ _ioproc(void *arg) XWindowEvent(_x.kbdcon, _x.drawable, KeyPressMask, &xevent); switch(xevent.type){ case KeyPress: - i = xtoplan9kbd(&xevent); + i = _xtoplan9kbd(&xevent); if(i == -1) continue; r = i; send(kc->c, &r); - while((i=xtoplan9kbd(nil)) >= 0){ + while((i=_xtoplan9kbd(nil)) >= 0){ r = i; send(kc->c, &r); } blob - e4e32bf2419d2bbb9d58d22c8fd1f40195ea9004 blob + 5292275a13fb531047f2814faa0092c6f7ef7c2a --- src/libdraw/x11-load.c +++ src/libdraw/x11-load.c @@ -13,7 +13,7 @@ loadmemimage(Memimage *i, Rectangle r, uchar *data, in n = _loadmemimage(i, r, data, ndata); if(n > 0 && i->X) - xputxdata(i, r); + _xputxdata(i, r); return n; } blob - afd47ccc4d52fa961b239054a0ab4ad6f5f4e01e blob + 1e84b92638553d829c764a46a9a95480f6c1189a --- src/libdraw/x11-memdraw.h +++ src/libdraw/x11-memdraw.h @@ -76,26 +76,26 @@ struct Xprivate { extern Xprivate _x; -extern Memimage *xallocmemimage(Rectangle, u32int, int); -extern XImage *xallocxdata(Memimage*, Rectangle); -extern void xdirtyxdata(Memimage*, Rectangle); -extern void xfillcolor(Memimage*, Rectangle, u32int); -extern void xfreexdata(Memimage*); -extern XImage *xgetxdata(Memimage*, Rectangle); -extern void xputxdata(Memimage*, Rectangle); +extern Memimage *_xallocmemimage(Rectangle, u32int, int); +extern XImage *_xallocxdata(Memimage*, Rectangle); +extern void _xdirtyxdata(Memimage*, Rectangle); +extern void _xfillcolor(Memimage*, Rectangle, u32int); +extern void _xfreexdata(Memimage*); +extern XImage *_xgetxdata(Memimage*, Rectangle); +extern void _xputxdata(Memimage*, Rectangle); extern void _initdisplaymemimage(Display*, Memimage*); struct Mouse; -extern int xtoplan9mouse(XDisplay*, XEvent*, struct Mouse*); -extern int xtoplan9kbd(XEvent*); -extern void xexpose(XEvent*, XDisplay*); -extern int xselect(XEvent*, XDisplay*); -extern int xconfigure(XEvent*, XDisplay*); -extern int xdestroy(XEvent*, XDisplay*); -extern void flushmemscreen(Rectangle); -extern void xmoveto(Point); +extern int _xtoplan9mouse(XDisplay*, XEvent*, struct Mouse*); +extern int _xtoplan9kbd(XEvent*); +extern void _xexpose(XEvent*, XDisplay*); +extern int _xselect(XEvent*, XDisplay*); +extern int _xconfigure(XEvent*, XDisplay*); +extern int _xdestroy(XEvent*, XDisplay*); +extern void _flushmemscreen(Rectangle); +extern void _xmoveto(Point); struct Cursor; -extern void xsetcursor(struct Cursor*); +extern void _xsetcursor(struct Cursor*); #define MouseMask (\ ButtonPressMask|\ blob - eae26788d834cb330f0def04e26418fbd7a0afb1 blob + 9e5143c65d8e0cbc938fb5f6fd3b5ea3d0b5b050 --- src/libdraw/x11-mouse.c +++ src/libdraw/x11-mouse.c @@ -11,7 +11,7 @@ void moveto(Mousectl *m, Point pt) { - xmoveto(pt); + _xmoveto(pt); } void @@ -64,10 +64,10 @@ _ioproc(void *arg) XNextEvent(_x.mousecon, &xevent); switch(xevent.type){ case Expose: - xexpose(&xevent, _x.mousecon); + _xexpose(&xevent, _x.mousecon); continue; case DestroyNotify: - if(xdestroy(&xevent, _x.mousecon)){ + if(_xdestroy(&xevent, _x.mousecon)){ /* drain it before sending */ /* apps that care can notice we sent a 0 */ /* otherwise we'll have getwindow send SIGHUP */ @@ -77,16 +77,16 @@ _ioproc(void *arg) } continue; case ConfigureNotify: - if(xconfigure(&xevent, _x.mousecon)) + if(_xconfigure(&xevent, _x.mousecon)) nbsend(mc->resizec, &one); continue; case SelectionRequest: - xselect(&xevent, _x.mousecon); + _xselect(&xevent, _x.mousecon); continue; case ButtonPress: case ButtonRelease: case MotionNotify: - if(xtoplan9mouse(_x.mousecon, &xevent, &m) < 0) + if(_xtoplan9mouse(_x.mousecon, &xevent, &m) < 0) continue; send(mc->c, &m); /* @@ -117,6 +117,6 @@ initmouse(char *file, Image *i) void setcursor(Mousectl *mc, Cursor *c) { - xsetcursor(c); + _xsetcursor(c); } blob - 8635b0ba456d044c252552f6971bced7df24bf11 blob + 22dfc60634848e17d826195a65799e254b16e8f2 --- src/libdraw/x11-pixelbits.c +++ src/libdraw/x11-pixelbits.c @@ -10,7 +10,7 @@ u32int pixelbits(Memimage *m, Point p) { if(m->X) - xgetxdata(m, Rect(p.x, p.y, p.x+1, p.y+1)); + _xgetxdata(m, Rect(p.x, p.y, p.x+1, p.y+1)); return _pixelbits(m, p); } blob - 3e8a635c1bc04d579c4fab8acb331156a6229fd6 blob + 471ca880952441f5538d748a35badec54d58b791 --- src/libdraw/x11-unload.c +++ src/libdraw/x11-unload.c @@ -10,7 +10,7 @@ int unloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) { if(i->X) - xgetxdata(i, r); + _xgetxdata(i, r); return _unloadmemimage(i, r, data, ndata); } blob - b34df3406ca2bac4e14f258e9c9086f92efedfa5 blob + 91d4af174d2f2410d8292e1e01538920883e046e --- src/libfs/fs.c +++ src/libfs/fs.c @@ -50,7 +50,7 @@ fsroot(Fsys *fs) } Fsys* -fsmount(int fd) +fsmount(int fd, char *aname) { int n; char *user; @@ -62,13 +62,14 @@ fsmount(int fd) strcpy(fs->version, "9P2000"); if((n = fsversion(fs, 8192, fs->version, sizeof fs->version)) < 0){ Error: + fs->fd = -1; fsunmount(fs); return nil; } fs->msize = n; user = getuser(); - if((fs->root = fsattach(fs, nil, getuser(), "")) == nil) + if((fs->root = fsattach(fs, nil, getuser(), aname)) == nil) goto Error; return fs; } @@ -76,6 +77,8 @@ fsmount(int fd) void fsunmount(Fsys *fs) { + fsclose(fs->root); + fs->root = nil; _fsdecref(fs); } @@ -85,7 +88,9 @@ _fsdecref(Fsys *fs) Fid *f, *next; qlock(&fs->lk); - if(--fs->ref == 0){ + --fs->ref; + //fprint(2, "fsdecref %p to %d\n", fs, fs->ref); + if(fs->ref == 0){ close(fs->fd); for(f=fs->freefid; f; f=next){ next = f->next; @@ -103,6 +108,7 @@ fsversion(Fsys *fs, int msize, char *version, int nver void *freep; Fcall tx, rx; + tx.tag = 0; tx.type = Tversion; tx.version = version; tx.msize = msize; @@ -120,9 +126,13 @@ fsattach(Fsys *fs, Fid *afid, char *user, char *aname) Fcall tx, rx; Fid *fid; + if(aname == nil) + aname = ""; + if((fid = _fsgetfid(fs)) == nil) return nil; + tx.tag = 0; tx.type = Tattach; tx.afid = afid ? afid->fid : NOFID; tx.fid = fid->fid; @@ -145,12 +155,11 @@ fsrpc(Fsys *fs, Fcall *tx, Fcall *rx, void **freep) n = sizeS2M(tx); tpkt = malloc(n); -fprint(2, "tpkt %p\n", tpkt); if(freep) *freep = nil; if(tpkt == nil) return -1; - fprint(2, "<- %F\n", tx); + //fprint(2, "<- %F\n", tx); nn = convS2M(tx, tpkt, n); if(nn != n){ free(tpkt); @@ -159,20 +168,18 @@ fprint(2, "tpkt %p\n", tpkt); return -1; } rpkt = muxrpc(&fs->mux, tpkt); -fprint(2, "tpkt %p\n", tpkt); free(tpkt); -fprint(2, "tpkt freed\n"); if(rpkt == nil) return -1; n = GBIT32((uchar*)rpkt); nn = convM2S(rpkt, n, rx); if(nn != n){ free(rpkt); - werrstr("libfs: convM2S packet size mismatch"); + werrstr("libfs: convM2S packet size mismatch %d %d", n, nn); fprint(2, "%r\n"); return -1; } - fprint(2, "-> %F\n", rx); + //fprint(2, "-> %F\n", rx); if(rx->type == Rerror){ werrstr("%s", rx->ename); free(rpkt); @@ -208,13 +215,13 @@ _fsgetfid(Fsys *fs) f[i].fid = fs->nextfid++; f[i].next = &f[i+1]; f[i].fs = fs; - fs->ref++; } f[i-1].next = nil; fs->freefid = f; } f = fs->freefid; fs->freefid = f->next; + fs->ref++; qunlock(&fs->lk); return f; } @@ -259,7 +266,7 @@ _fsrecv(Mux *mux) { uchar *pkt; uchar buf[4]; - int n; + int n, nfd; Fsys *fs; fs = mux->aux; @@ -277,11 +284,13 @@ _fsrecv(Mux *mux) free(pkt); return nil; } -#if 0 if(pkt[4] == Ropenfd){ - /* do unix socket crap */ - sysfatal("no socket crap implemented"); + if((nfd=recvfd(fs->fd)) < 0){ + fprint(2, "recv fd error: %r\n"); + free(pkt); + return nil; + } + PBIT32(pkt+n-4, nfd); } -#endif return pkt; } blob - acfb0ae5990ba8fdbdfb4eba69913ff94ec5c756 blob + d4c8b49fe3573074cf606e298951aa860616f2e9 --- src/libfs/mkfile +++ src/libfs/mkfile @@ -8,7 +8,9 @@ OFILES=\ create.$O\ dirread.$O\ fs.$O\ + ns.$O\ open.$O\ + openfd.$O\ read.$O\ stat.$O\ walk.$O\ blob - b1fdeb039b6eb327e7220d6b9431179dc2b1d22c blob + bc63260249f41bc3b75fd6e1d41d3b3f92f62a69 --- src/libmux/mux.c +++ src/libmux/mux.c @@ -173,6 +173,5 @@ puttag(Mux *mux, Muxrpc *r) mux->nwait--; mux->freetag = i; rwakeup(&mux->tagrend); -fprint(2, "free %p\n", r); free(r); } blob - 8678d753fa954b55073739bc5a4cecf6d72c9be7 blob + fcade7f4c9a0885db50e98668d0582b14e1d6642 --- src/libplumb/mesg.c +++ src/libplumb/mesg.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include "plumb.h" static char attrbuf[4096]; @@ -9,35 +11,15 @@ char *home; int plumbopen(char *name, int omode) { -#if 0 - int fd, f; - char *s; -#endif - char buf[256]; + Fsys *fs; + int fd; - if(name[0] == '/') - return open(name, omode); - if(home == nil){ - home = getenv("HOME"); - if(home == nil) - return -1; - } - snprint(buf, sizeof buf, "%s/mnt/plumb", home); -#if 0 - fd = open(buf, omode); - if(fd >= 0) - return fd; - snprint(buf, sizeof buf, "/mnt/term/mnt/plumb/%s", name); - fd = open(buf, omode); - if(fd >= 0) - return fd; - /* try mounting service */ - s = getenv("plumbsrv"); - if(s == nil) + fs = nsmount("plumb", ""); + if(fs == nil) return -1; - snprint(buf, sizeof buf, "/mnt/plumb/%s", name); -#endif - return open(buf, omode); + fd = fsopenfd(fs, name, omode); + fsunmount(fs); + return fd; } static int blob - 7cad85cc70b800972d718bd7e66983e8ee588280 blob + 074556f9b50819c8d8525aefdd419a2851cdbb92 --- src/libthread/asm-FreeBSD-386.s +++ src/libthread/asm-FreeBSD-386.s @@ -41,9 +41,9 @@ _xdec: movl 4(%esp), %eax lock decl 0(%eax) jz iszero - movl %eax, 1 + movl $1, %eax ret iszero: - movl %eax, 0 + movl $0, %eax ret blob - 55f6c60cfb1ae78885bd52ace003667003cdfea8 blob + d487e1954f41b7fb187d8384770f7e1185f84de4 --- src/libthread/create.c +++ src/libthread/create.c @@ -1,9 +1,8 @@ #include "threadimpl.h" Pqueue _threadpq; +int _threadprocs; -int _threadmultiproc; - static int nextID(void); /* @@ -90,7 +89,6 @@ proccreate(void (*f)(void*), void *arg, uint stacksize werrstr("cannot create procs once there is an idle thread"); return -1; } - _threadmultiproc = 1; return procrfork(f, arg, stacksize, 0); } @@ -125,11 +123,12 @@ threadcreateidle(void (*f)(void *arg), void *arg, uint { int id; - if(_threadmultiproc){ + if(_threadprocs!=1){ werrstr("cannot have idle thread in multi-proc program"); return -1; } id = newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp()); + _threaddebug(DBGSCHED, "idle is %d", id); _threadidle(); return id; } @@ -154,6 +153,7 @@ _newproc(void (*f)(void *arg), void *arg, uint stacksi else *_threadpq.tail = p; _threadpq.tail = &p->next; + _threadprocs++; unlock(&_threadpq.lock); return p; } blob - ef50bf198e07766922459e71095027eb28da0f41 blob + 97c756079abe0771ca6d34141a4f2078e49d5a71 --- src/libthread/exec-unix.c +++ src/libthread/exec-unix.c @@ -3,7 +3,7 @@ #include "threadimpl.h" void -procexec(Channel *pidc, char *prog, char *args[]) +procexec(Channel *pidc, int fd[3], char *prog, char *args[]) { int n; Proc *p; @@ -45,6 +45,7 @@ procexec(Channel *pidc, char *prog, char *args[]) assert(p->needexec==0); p->exec.prog = prog; p->exec.args = args; + p->exec.stdfd = fd; p->needexec = 1; _sched(); @@ -56,7 +57,11 @@ procexec(Channel *pidc, char *prog, char *args[]) goto Bad; } close(p->exec.fd[0]); - + close(fd[0]); + if(fd[1] != fd[0]) + close(fd[1]); + if(fd[2] != fd[1] && fd[2] != fd[0]) + close(fd[2]); if(pidc) sendul(pidc, t->ret); @@ -66,9 +71,9 @@ procexec(Channel *pidc, char *prog, char *args[]) } void -procexecl(Channel *pidc, char *f, ...) +procexecl(Channel *pidc, int fd[3], char *f, ...) { - procexec(pidc, f, &f+1); + procexec(pidc, fd, f, &f+1); } void @@ -107,10 +112,17 @@ efork(void *ve) { char buf[ERRMAX]; Execargs *e; + int i; e = ve; _threaddebug(DBGEXEC, "_schedexec %s -- calling execv", e->prog); - execv(e->prog, e->args); + dup(e->stdfd[0], 0); + dup(e->stdfd[1], 1); + dup(e->stdfd[2], 2); + for(i=3; i<40; i++) + if(i != e->fd[1]) + close(i); + execvp(e->prog, e->args); _threaddebug(DBGEXEC, "_schedexec failed: %r"); rerrstr(buf, sizeof buf); if(buf[0]=='\0') blob - bcf2080285eade1f75c0d9cd0ac4b465f2f754b6 blob + 0fb68111f178b479e17723fdf9a15107a29a2ea3 --- src/libthread/exec.c +++ src/libthread/exec.c @@ -3,7 +3,7 @@ #define PIPEMNT "/mnt/temp" void -procexec(Channel *pidc, char *prog, char *args[]) +procexec(Channel *pidc, int fd[3], char *prog, char *args[]) { int n; Proc *p; @@ -50,6 +50,7 @@ procexec(Channel *pidc, char *prog, char *args[]) assert(p->needexec==0); p->exec.prog = prog; p->exec.args = args; + p->exec.stdfd = fd; p->needexec = 1; _sched(); @@ -61,7 +62,11 @@ procexec(Channel *pidc, char *prog, char *args[]) goto Bad; } close(p->exec.fd[0]); - + close(fd[0]); + if(fd[1] != fd[0]) + close(fd[1]); + if(fd[2] != fd[1] && fd[2] != fd[0]) + close(fd[2]); if(pidc) sendul(pidc, t->ret); @@ -70,8 +75,8 @@ procexec(Channel *pidc, char *prog, char *args[]) } void -procexecl(Channel *pidc, char *f, ...) +procexecl(Channel *pidc, int fd[3], char *f, ...) { - procexec(pidc, f, &f+1); + procexec(pidc, fd, f, &f+1); } blob - 06c1293545f5cbeb749dc7baaf36a36f6f499195 blob + 97a6154afdb37d552ccf7ef92860b04ed8654f15 --- src/libthread/main.c +++ src/libthread/main.c @@ -37,7 +37,7 @@ main(int argc, char **argv) _systhreadinit(); _qlockinit(_threadrendezvous); _sysfatal = _threadsysfatal; -// notify(_threadnote); + notify(_threadnote); if(mainstacksize == 0) mainstacksize = 32*1024; @@ -98,6 +98,7 @@ _schedexit(Proc *p) break; } } + _threadprocs--; unlock(&_threadpq.lock); strncpy(ex, p->exitstr, sizeof ex); blob - b7f4b13752ae11ec0a7327b53553dc5ba1751724 blob + b25f2b23c336de568dfbae2a0d0cfea1a7c17c4b --- src/libthread/note.c +++ src/libthread/note.c @@ -2,7 +2,6 @@ int _threadnopasser; -#ifdef NOTDEF #define NFN 33 #define ERRLEN 48 typedef struct Note Note; @@ -85,7 +84,7 @@ _threadnote(void *v, char *s) Note *n; _threaddebug(DBGNOTE, "Got note %s", s); - if(strncmp(s, "sys:", 4) == 0) + if(strncmp(s, "sys:", 4) == 0 && strcmp(s, "sys: write on closed pipe") != 0) noted(NDFLT); // if(_threadexitsallstatus){ @@ -112,7 +111,6 @@ _threadnote(void *v, char *s) delayednotes(p, v); noted(NCONT); } -#endif int _procsplhi(void) blob - d6af1c7c0a9977e243f2fad904acaeaa751648ed blob + d85a76e21ec195ed692e604809e7a7fdb86d9de8 --- src/libthread/sched.c +++ src/libthread/sched.c @@ -98,17 +98,18 @@ runthread(Proc *p) q = &p->ready; lock(&p->readylock); if(q->head == nil){ - q->asleep = 1; if(p->idle){ if(p->idle->state != Ready){ fprint(2, "everyone is asleep\n"); exits("everyone is asleep"); } unlock(&p->readylock); + _threaddebug(DBGSCHED, "running idle thread", p->nthreads); return p->idle; } _threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads); + q->asleep = 1; unlock(&p->readylock); while(rendezvous((ulong)q, 0) == ~0){ if(_threadexitsallstatus) @@ -148,7 +149,7 @@ Resched: _threaddelproc(); _schedexit(p); } - // _threaddebug(DBGSCHED, "running %d.%d", t->proc->pid, t->id); + _threaddebug(DBGSCHED, "running %d.%d", t->proc->pid, t->id); p->thread = t; if(t->moribund){ _threaddebug(DBGSCHED, "%d.%d marked to die"); @@ -176,8 +177,10 @@ _threadready(Thread *t) { Tqueue *q; - if(t == t->proc->idle) + if(t == t->proc->idle){ + _threaddebug(DBGSCHED, "idle thread is ready"); return; + } assert(t->state == Ready); _threaddebug(DBGSCHED, "readying %d.%d", t->proc->pid, t->id); @@ -206,18 +209,25 @@ void _threadidle(void) { Tqueue *q; - Thread *t; + Thread *t, *idle; Proc *p; p = _threadgetproc(); q = &p->ready; lock(&p->readylock); - assert(q->head); - t = q->head; - q->head = t->next; - if(q->tail == t) + assert(q->tail); + idle = q->tail; + if(q->head == idle){ + q->head = nil; q->tail = nil; - p->idle = t; + }else{ + for(t=q->head; t->next!=q->tail; t=t->next) + ; + t->next = nil; + q->tail = t; + } + p->idle = idle; + _threaddebug(DBGSCHED, "p->idle is %d\n", idle->id); unlock(&p->readylock); } blob - aa69845cda2fc43adc2afa964b6be25538b9e2f6 blob + 0dd1e8704711fef5f0b05ef39d3f7addf41ffe86 --- src/libthread/threadimpl.h +++ src/libthread/threadimpl.h @@ -105,6 +105,7 @@ struct Execargs char *prog; char **args; int fd[2]; + int *stdfd; }; struct Proc @@ -214,4 +215,5 @@ extern void _stackfree(void*); extern int _threadgetpid(void); extern void _threadmemset(void*, int, int); extern void _threaddebugmemset(void*, int, int); +extern int _threadprocs;