diff options
author | rsc <devnull@localhost> | 2003-12-11 17:48:38 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2003-12-11 17:48:38 +0000 |
commit | 32f69c36e0eec1227934bbd34854bfebd88686f2 (patch) | |
tree | 1587e9de84816b77168afa81c1594cc686809910 | |
parent | ac244f8d287a6119155ea672c8fd13c487c5e4c7 (diff) | |
download | plan9port-32f69c36e0eec1227934bbd34854bfebd88686f2.tar.gz plan9port-32f69c36e0eec1227934bbd34854bfebd88686f2.tar.bz2 plan9port-32f69c36e0eec1227934bbd34854bfebd88686f2.zip |
Add support for user-level 9P servers/clients and various bug fixes to go with them.
60 files changed, 966 insertions, 486 deletions
@@ -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" diff --git a/include/fcall.h b/include/fcall.h index f85487bd..893b0504 100644 --- a/include/fcall.h +++ b/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*); diff --git a/include/fs.h b/include/fs.h index 219b2774..38442709 100644 --- a/include/fs.h +++ b/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 } diff --git a/include/lib9.h b/include/lib9.h index ce5187cd..de082499 100644 --- a/include/lib9.h +++ b/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 <fmt.h>) @@ -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); <unistd.h> */ +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*); <unistd.h> */ -/* extern int chdir(char*); <unistd.h> */ +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); <unistd.h> */ +extern int p9open(char*, int); extern int fd2path(int, char*, int); -extern int pipe(int*); +extern int p9pipe(int*); /* * use defs from <unistd.h> 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 diff --git a/include/thread.h b/include/thread.h index e9dc96e0..0eb02b52 100644 --- a/include/thread.h +++ b/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); diff --git a/plumb/basic b/plumb/basic index a065799e..918cc51b 100644 --- a/plumb/basic +++ b/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 edit -a ''action=showdata # 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 (.*)' diff --git a/src/cmd/9p.c b/src/cmd/9p.c index 7c018c34..e9481746 100644 --- a/src/cmd/9p.c +++ b/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; diff --git a/src/cmd/9pserve.c b/src/cmd/9pserve.c index ad77236e..c33beb14 100644 --- a/src/cmd/9pserve.c +++ b/src/cmd/9pserve.c @@ -2,6 +2,8 @@ #include <libc.h> #include <fcall.h> #include <thread.h> +#include <poll.h> +#include <errno.h> 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,7 +183,22 @@ 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 @@ -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,7 +446,155 @@ 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 @@ -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); - fidput(m->afid); - fidput(m->newfid); - free(m->tpkt); - free(m->rpkt); m->fid = nil; + fidput(m->afid); 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; i<npfd; i++) + pfd[i].revents = 0; + if(verbose){ + fprint(2, "poll:"); + for(i=0; i<npfd; i++) + if(pfd[i].events) + fprint(2, " %d%c", pfd[i].fd, pfd[i].events==POLLIN ? 'r' : pfd[i].events==POLLOUT ? 'w' : '?'); + fprint(2, "\n"); + } + n = poll(pfd, npfd, -1); + if(n <= 0) + continue; + for(i=0; i<npfd; i++) + if(pfd[i].fd != -1 && pfd[i].revents){ + pfd[i].fd = -1; + pfd[i].events = 0; + pfd[i].revents = 0; + nbsendul(pio[i]->c, 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; tot<n; tot+=m){ + m = ioread(io, fd, u+tot, n-tot); + if(m <= 0){ + if(tot) + break; + return m; + } + } + return tot; +} + +int +iorecvfd(Ioproc *io, int fd) { + int r; + + noblock(fd); + while((r=recvfd(fd)) < 0 && errno == EWOULDBLOCK) + rwait(io, fd); + return r; +} + +int +iosendfd(Ioproc *io, int s, int fd) +{ + int r; + + noblock(s); + while((r=sendfd(s, fd)) < 0 && errno == EWOULDBLOCK) + wwait(io, s); +if(r < 0) fprint(2, "sent %d, %d\n", s, fd); + return r; +} + +static long +_iowrite(Ioproc *io, int fd, void *v, long n) +{ + long r; USED(io); - xxx; + noblock(fd); + while((r=write(fd, v, n)) < 0 && errno == EWOULDBLOCK) + wwait(io, fd); + return r; +} + +long +iowrite(Ioproc *io, int fd, void *v, long n) +{ + long tot, m; + uchar *u; + + u = v; + for(tot=0; tot<n; tot+=m){ + m = _iowrite(io, fd, u+tot, n-tot); + if(m <= 0){ + if(tot) + break; + return m; + } + } + return tot; } int -iolisten(Ioproc *io, char *a, char *b) +iolisten(Ioproc *io, char *dir, char *ndir) { + int fd; + int r; + extern int _p9netfd(char*); USED(io); - xxx; + if((fd = _p9netfd(dir)) < 0) + return -1; + noblock(fd); + while((r=listen(dir, ndir)) < 0 && errno == EWOULDBLOCK) + rwait(io, fd); + return r; } int ioaccept(Ioproc *io, int fd, char *dir) { + int r; USED(io); - xxx; + noblock(fd); + while((r=accept(fd, dir)) < 0 && errno == EWOULDBLOCK) + rwait(io, fd); + return r; } #else diff --git a/src/cmd/9term/9term.c b/src/cmd/9term/9term.c index ef51d864..cfee0013 100644 --- a/src/cmd/9term/9term.c +++ b/src/cmd/9term/9term.c @@ -1212,7 +1212,6 @@ rcstart(int fd[2], int argc, char **argv) argv[1] = "-i"; argv[2] = 0; } - /* * fd0 is slave (tty), fd1 is master (pty) */ @@ -1222,7 +1221,7 @@ rcstart(int fd[2], int argc, char **argv) switch(pid = fork()) { case 0: - putenv("TERM=9term"); + putenv("TERM", "9term"); close(fd[1]); setsid(); // tcsetpgrp(0, pid); @@ -1238,6 +1237,7 @@ rcstart(int fd[2], int argc, char **argv) dup(sfd, 2); system("stty tabs -onlcr -echo"); execvp(argv[0], argv); + fprint(2, "exec %s failed: %r\n", argv[0]); _exits("oops"); break; case -1: @@ -1388,9 +1388,7 @@ scroll(int but) void plumbstart(void) { - char buf[256]; - snprint(buf, sizeof buf, "%s/mnt/plumb", getenv("HOME")); - if((plumbfd = plumbopen(buf, OWRITE)) < 0) + if((plumbfd = plumbopen("send", OWRITE)) < 0) fatal("plumbopen"); } diff --git a/src/cmd/9term/mkfile b/src/cmd/9term/mkfile index d7d4a6d0..2706dda6 100644 --- a/src/cmd/9term/mkfile +++ b/src/cmd/9term/mkfile @@ -9,5 +9,5 @@ OFILES=\ <$PLAN9/src/mkone -LDFLAGS=-lframe -ldraw -lplumb -lthread -l9 -lfmt -lutf -L$X11/lib -lX11 -lutil +LDFLAGS=-lframe -ldraw -lplumb -lfs -lmux -lthread -l9 -lfmt -lutf -L$X11/lib -lX11 -lutil diff --git a/src/cmd/dc.c b/src/cmd/dc.c index 21967de1..daff401d 100644 --- a/src/cmd/dc.c +++ b/src/cmd/dc.c @@ -21,6 +21,7 @@ typedef void* pointer; #define NE 3 #define length(p) ((p)->wt-(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 diff --git a/src/cmd/dict/dict.c b/src/cmd/dict/dict.c index dccd3037..8cbf6aac 100644 --- a/src/cmd/dict/dict.c +++ b/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); diff --git a/src/cmd/dict/utils.c b/src/cmd/dict/utils.c index 8e4db9e9..6916d549 100644 --- a/src/cmd/dict/utils.c +++ b/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} diff --git a/src/cmd/mkfile b/src/cmd/mkfile index 8450d94b..e2131e77 100644 --- a/src/cmd/mkfile +++ b/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 diff --git a/src/cmd/plumb/fsys.c b/src/cmd/plumb/fsys.c index 6f95a23a..912e5ca0 100644 --- a/src/cmd/plumb/fsys.c +++ b/src/cmd/plumb/fsys.c @@ -3,14 +3,13 @@ #include <bio.h> #include <regexp.h> #include <thread.h> -#include <auth.h> #include <fcall.h> #include <plumb.h> #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, Exec *e) } 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; i<ndir; i++) flushqueue(&dir[i], t->oldtag); @@ -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){ diff --git a/src/cmd/plumb/match.c b/src/cmd/plumb/match.c index 42a9232f..dc1abbb1 100644 --- a/src/cmd/plumb/match.c +++ b/src/cmd/plumb/match.c @@ -6,6 +6,7 @@ #include <plumb.h> #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 click) 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 args[NARGCHAR]) 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"); } diff --git a/src/cmd/plumb/mkfile b/src/cmd/plumb/mkfile index d6a14654..6550387f 100644 --- a/src/cmd/plumb/mkfile +++ b/src/cmd/plumb/mkfile @@ -1,10 +1,9 @@ -</$objtype/mkfile +PLAN9=../../.. +<$PLAN9/src/mkhdr TARG=plumber plumb - -BIN=/$objtype/bin -</sys/src/cmd/mkmany +<$PLAN9/src/mkmany PLUMBER=plumber.$O fsys.$O match.$O rules.$O PLUMB=plumb.$O @@ -15,6 +14,4 @@ $PLUMB: $HFILES $O.plumb: $PLUMB $O.plumber: $PLUMBER -syms:V: - 8c -a plumber.c >syms - 8c -aa fsys.c match.c rules.c >>syms +LDFLAGS=$LDFLAGS -lplumb -lfs -lmux -lthread -lregexp9 -l9 -lbio -lfmt -lutf diff --git a/src/cmd/plumb/plumber.c b/src/cmd/plumb/plumber.c index d0bd9c14..424469f2 100644 --- a/src/cmd/plumb/plumber.c +++ b/src/cmd/plumb/plumber.c @@ -3,10 +3,10 @@ #include <regexp.h> #include <thread.h> #include <plumb.h> -#include <auth.h> #include <fcall.h> #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){ diff --git a/src/cmd/plumb/plumber.h b/src/cmd/plumb/plumber.h index 0d1205f9..4b9267a5 100644 --- a/src/cmd/plumb/plumber.h +++ b/src/cmd/plumb/plumber.h @@ -91,3 +91,4 @@ jmp_buf parsejmp; char *lasterror; char **ports; int nports; +int debug; diff --git a/src/cmd/plumb/rules.c b/src/cmd/plumb/rules.c index 262f6d67..b51bb61f 100644 --- a/src/cmd/plumb/rules.c +++ b/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); } diff --git a/src/cmd/rc/plan9ish.c b/src/cmd/rc/plan9ish.c index 1b250ba1..abb66cc3 100644 --- a/src/cmd/rc/plan9ish.c +++ b/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); diff --git a/src/cmd/sam/unix.c b/src/cmd/sam/unix.c index 45cfc3bc..b8a67b90 100644 --- a/src/cmd/sam/unix.c +++ b/src/cmd/sam/unix.c @@ -214,92 +214,4 @@ erealloc(void *p, ulong n) 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 <lib9.h> - -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 diff --git a/src/cmd/yacc.c b/src/cmd/yacc.c index 05e9d589..d9e30761 100644 --- a/src/cmd/yacc.c +++ b/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) diff --git a/src/lib9/announce.c b/src/lib9/announce.c index 04c712d9..9f07bd22 100644 --- a/src/lib9/announce.c +++ b/src/lib9/announce.c @@ -5,13 +5,14 @@ #include <sys/socket.h> #include <netinet/in.h> #include <sys/un.h> +#include <errno.h> #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; } diff --git a/src/lib9/await.c b/src/lib9/await.c index 89c695ae..5f2d58ba 100644 --- a/src/lib9/await.c +++ b/src/lib9/await.c @@ -45,6 +45,7 @@ static struct { #endif SIGUSR1, "sys: usr1", SIGUSR2, "sys: usr2", + SIGPIPE, "sys: write on closed pipe", }; char* diff --git a/src/lib9/convM2S.c b/src/lib9/convM2S.c index fcdcd42d..920775ea 100644 --- a/src/lib9/convM2S.c +++ b/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: diff --git a/src/lib9/convS2M.c b/src/lib9/convS2M.c index 9acdcfa5..6e9d2719 100644 --- a/src/lib9/convS2M.c +++ b/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: diff --git a/src/lib9/create.c b/src/lib9/create.c index abef0c35..bdad5f6a 100644 --- a/src/lib9/create.c +++ b/src/lib9/create.c @@ -1,8 +1,54 @@ #include <u.h> +#define NOPLAN9DEFINES #include <libc.h> +#include <sys/stat.h> + +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; } diff --git a/src/lib9/fcallfmt.c b/src/lib9/fcallfmt.c index 4eef88de..592316fe 100644 --- a/src/lib9/fcallfmt.c +++ b/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; diff --git a/src/lib9/getenv.c b/src/lib9/getenv.c index c6ff7160..2a2d1391 100644 --- a/src/lib9/getenv.c +++ b/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; +} diff --git a/src/lib9/mkfile b/src/lib9/mkfile index 14d8c0e0..a0e75fc3 100644 --- a/src/lib9/mkfile +++ b/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\ diff --git a/src/lib9/notify.c b/src/lib9/notify.c index 460eabfe..160755d0 100644 --- a/src/lib9/notify.c +++ b/src/lib9/notify.c @@ -19,7 +19,7 @@ static int sigs[] = { #endif SIGFPE, SIGBUS, - SIGSEGV, +/* SIGSEGV, */ SIGSYS, SIGPIPE, SIGALRM, diff --git a/src/lib9/rfork.c b/src/lib9/rfork.c index 270c3cdd..f3a21928 100644 --- a/src/lib9/rfork.c +++ b/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; diff --git a/src/libdraw/openfont.c b/src/libdraw/openfont.c index a1ff278a..0b3dc253 100644 --- a/src/libdraw/openfont.c +++ b/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; diff --git a/src/libdraw/x11-alloc.c b/src/libdraw/x11-alloc.c index 458efc61..9a6585cb 100644 --- a/src/libdraw/x11-alloc.c +++ b/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 diff --git a/src/libdraw/x11-cload.c b/src/libdraw/x11-cload.c index 25a325c6..7a84a983 100644 --- a/src/libdraw/x11-cload.c +++ b/src/libdraw/x11-cload.c @@ -13,7 +13,7 @@ cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) n = _cloadmemimage(i, r, data, ndata); if(n > 0 && i->X) - xputxdata(i, r); + _xputxdata(i, r); return n; } diff --git a/src/libdraw/x11-draw.c b/src/libdraw/x11-draw.c index 97438740..6373e4e3 100644 --- a/src/libdraw/x11-draw.c +++ b/src/libdraw/x11-draw.c @@ -24,11 +24,11 @@ memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp, /* 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, Point sp, 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; } diff --git a/src/libdraw/x11-event.c b/src/libdraw/x11-event.c index 408eb419..ba9d031b 100644 --- a/src/libdraw/x11-event.c +++ b/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); } diff --git a/src/libdraw/x11-fill.c b/src/libdraw/x11-fill.c index ff0b2e86..33fc6a2a 100644 --- a/src/libdraw/x11-fill.c +++ b/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; diff --git a/src/libdraw/x11-get.c b/src/libdraw/x11-get.c index a6d4b12e..693b2938 100644 --- a/src/libdraw/x11-get.c +++ b/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; diff --git a/src/libdraw/x11-init.c b/src/libdraw/x11-init.c index 6f87b412..fb6a9144 100644 --- a/src/libdraw/x11-init.c +++ b/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; diff --git a/src/libdraw/x11-itrans.c b/src/libdraw/x11-itrans.c index 0c992449..8e72b011 100644 --- a/src/libdraw/x11-itrans.c +++ b/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 property=%d selection=%d\n", void putsnarf(char *data) { - xputsnarf(_x.snarfcon, data); + _xputsnarf(_x.snarfcon, data); } char* getsnarf(void) { - return xgetsnarf(_x.snarfcon); + return _xgetsnarf(_x.snarfcon); } diff --git a/src/libdraw/x11-keyboard.c b/src/libdraw/x11-keyboard.c index 443074e9..676027e3 100644 --- a/src/libdraw/x11-keyboard.c +++ b/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); } diff --git a/src/libdraw/x11-load.c b/src/libdraw/x11-load.c index e4e32bf2..5292275a 100644 --- a/src/libdraw/x11-load.c +++ b/src/libdraw/x11-load.c @@ -13,7 +13,7 @@ loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) n = _loadmemimage(i, r, data, ndata); if(n > 0 && i->X) - xputxdata(i, r); + _xputxdata(i, r); return n; } diff --git a/src/libdraw/x11-memdraw.h b/src/libdraw/x11-memdraw.h index afd47ccc..1e84b926 100644 --- a/src/libdraw/x11-memdraw.h +++ b/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|\ diff --git a/src/libdraw/x11-mouse.c b/src/libdraw/x11-mouse.c index eae26788..9e5143c6 100644 --- a/src/libdraw/x11-mouse.c +++ b/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); } diff --git a/src/libdraw/x11-pixelbits.c b/src/libdraw/x11-pixelbits.c index 8635b0ba..22dfc606 100644 --- a/src/libdraw/x11-pixelbits.c +++ b/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); } diff --git a/src/libdraw/x11-unload.c b/src/libdraw/x11-unload.c index 3e8a635c..471ca880 100644 --- a/src/libdraw/x11-unload.c +++ b/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); } diff --git a/src/libfs/fs.c b/src/libfs/fs.c index b34df340..91d4af17 100644 --- a/src/libfs/fs.c +++ b/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 nversion) 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; } diff --git a/src/libfs/mkfile b/src/libfs/mkfile index acfb0ae5..d4c8b49f 100644 --- a/src/libfs/mkfile +++ b/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\ diff --git a/src/libmux/mux.c b/src/libmux/mux.c index b1fdeb03..bc632602 100644 --- a/src/libmux/mux.c +++ b/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); } diff --git a/src/libplumb/mesg.c b/src/libplumb/mesg.c index 8678d753..fcade7f4 100755 --- a/src/libplumb/mesg.c +++ b/src/libplumb/mesg.c @@ -1,5 +1,7 @@ #include <u.h> #include <libc.h> +#include <fcall.h> +#include <fs.h> #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 diff --git a/src/libthread/asm-FreeBSD-386.s b/src/libthread/asm-FreeBSD-386.s index 7cad85cc..074556f9 100644 --- a/src/libthread/asm-FreeBSD-386.s +++ b/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 diff --git a/src/libthread/create.c b/src/libthread/create.c index 55f6c60c..d487e195 100644 --- a/src/libthread/create.c +++ b/src/libthread/create.c @@ -1,8 +1,7 @@ #include "threadimpl.h" Pqueue _threadpq; - -int _threadmultiproc; +int _threadprocs; 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 stacksize) { 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 stacksize, char *name, int grp, i else *_threadpq.tail = p; _threadpq.tail = &p->next; + _threadprocs++; unlock(&_threadpq.lock); return p; } diff --git a/src/libthread/exec-unix.c b/src/libthread/exec-unix.c index ef50bf19..97c75607 100644 --- a/src/libthread/exec-unix.c +++ b/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') diff --git a/src/libthread/exec.c b/src/libthread/exec.c index bcf20802..0fb68111 100644 --- a/src/libthread/exec.c +++ b/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); } diff --git a/src/libthread/main.c b/src/libthread/main.c index 06c12935..97a6154a 100644 --- a/src/libthread/main.c +++ b/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); diff --git a/src/libthread/note.c b/src/libthread/note.c index b7f4b137..b25f2b23 100644 --- a/src/libthread/note.c +++ b/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) diff --git a/src/libthread/sched.c b/src/libthread/sched.c index d6af1c7c..d85a76e2 100644 --- a/src/libthread/sched.c +++ b/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); } diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index aa69845c..0dd1e870 100644 --- a/src/libthread/threadimpl.h +++ b/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; |