Add support for user-level 9P servers/clients and various bug fixes to go with them.

This commit is contained in:
rsc 2003-12-11 17:48:38 +00:00
parent ac244f8d28
commit 32f69c36e0
60 changed files with 965 additions and 485 deletions

6
bin/B
View file

@ -6,6 +6,12 @@ then
exit 1 exit 1
fi fi
for i
do
plumb $i
done
exit 0
if [ "x$DISPLAY" = "x" ] if [ "x$DISPLAY" = "x" ]
then then
sam="/tmp/.sam.$USER" sam="/tmp/.sam.$USER"

View file

@ -40,6 +40,7 @@ struct Fcall
char *data; /* Twrite, Rread */ char *data; /* Twrite, Rread */
ushort nstat; /* Twstat, Rstat */ ushort nstat; /* Twstat, Rstat */
uchar *stat; /* Twstat, Rstat */ uchar *stat; /* Twstat, Rstat */
int unixfd; /* Ropenfd */
} Fcall; } Fcall;
@ -100,6 +101,9 @@ enum
Twstat = 126, Twstat = 126,
Rwstat, Rwstat,
Tmax, Tmax,
Topenfd = 98,
Ropenfd,
}; };
uint convM2S(uchar*, uint, Fcall*); uint convM2S(uchar*, uint, Fcall*);

View file

@ -12,7 +12,7 @@ typedef struct Fsys Fsys;
typedef struct Fid Fid; typedef struct Fid Fid;
Fsys *fsinit(int); Fsys *fsinit(int);
Fsys *fsmount(int); Fsys *fsmount(int, char*);
int fsversion(Fsys*, int, char*, int); int fsversion(Fsys*, int, char*, int);
Fid *fsauth(Fsys*, char*); Fid *fsauth(Fsys*, char*);
@ -34,6 +34,7 @@ struct Dir *fsdirfstat(Fid*);
int fsdirwstat(Fsys*, char*, struct Dir*); int fsdirwstat(Fsys*, char*, struct Dir*);
int fsdirfwstat(Fid*, struct Dir*); int fsdirfwstat(Fid*, struct Dir*);
Fid *fsroot(Fsys*); Fid *fsroot(Fsys*);
Fsys *nsmount(char*, char*);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -194,6 +194,7 @@ extern int isupperrune(Rune);
* *
extern void* malloc(ulong); extern void* malloc(ulong);
*/ */
extern void* p9malloc(ulong);
extern void* mallocz(ulong, int); extern void* mallocz(ulong, int);
/* /*
extern void free(void*); extern void free(void*);
@ -208,6 +209,9 @@ extern ulong getrealloctag(void*);
/* /*
extern void* malloctopoolblock(void*); extern void* malloctopoolblock(void*);
*/ */
#ifndef NOPLAN9DEFINES
#define malloc p9malloc
#endif
/* /*
* print routines (provided by <fmt.h>) * print routines (provided by <fmt.h>)
@ -442,6 +446,7 @@ extern void exits(char*);
extern double frexp(double, int*); extern double frexp(double, int*);
extern ulong getcallerpc(void*); extern ulong getcallerpc(void*);
extern char* p9getenv(char*); extern char* p9getenv(char*);
extern int p9putenv(char*, char*);
extern int getfields(char*, char**, int, int, char*); extern int getfields(char*, char**, int, int, char*);
extern int gettokens(char *, char **, int, char *); extern int gettokens(char *, char **, int, char *);
extern char* getuser(void); extern char* getuser(void);
@ -482,6 +487,7 @@ extern long time(long*);
#define longjmp p9longjmp #define longjmp p9longjmp
#undef setjmp #undef setjmp
#define setjmp p9setjmp #define setjmp p9setjmp
#define putenv p9putenv
#define notejmp p9notejmp #define notejmp p9notejmp
#define jmp_buf p9jmp_buf #define jmp_buf p9jmp_buf
#endif #endif
@ -728,14 +734,14 @@ struct IOchunk
extern void _exits(char*); extern void _exits(char*);
extern void abort(void); extern void abort(void);
/* extern int access(char*, int); <unistd.h> */ extern int p9access(char*, int);
extern long p9alarm(ulong); extern long p9alarm(ulong);
extern int await(char*, int); extern int await(char*, int);
/* extern int bind(char*, char*, int); give up */ /* extern int bind(char*, char*, int); give up */
/* extern int brk(void*); <unistd.h> */ /* extern int brk(void*); <unistd.h> */
/* extern int chdir(char*); <unistd.h> */ extern int p9chdir(char*);
extern int close(int); extern int close(int);
extern int create(char*, int, ulong); extern int p9create(char*, int, ulong);
extern int p9dup(int, int); extern int p9dup(int, int);
extern int errstr(char*, uint); extern int errstr(char*, uint);
extern int p9exec(char*, char*[]); extern int p9exec(char*, char*[]);
@ -752,9 +758,9 @@ extern int unmount(char*, char*);
*/ */
extern int noted(int); extern int noted(int);
extern int notify(void(*)(void*, char*)); 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 fd2path(int, char*, int);
extern int pipe(int*); extern int p9pipe(int*);
/* /*
* use defs from <unistd.h> * use defs from <unistd.h>
extern long pread(int, void*, long, vlong); extern long pread(int, void*, long, vlong);
@ -796,6 +802,10 @@ extern ulong rendezvous(ulong, ulong);
#define wait p9wait #define wait p9wait
#define waitpid p9waitpid #define waitpid p9waitpid
#define rfork p9rfork #define rfork p9rfork
#define access p9access
#define create p9create
#define open p9open
#define pipe p9pipe
#endif #endif
extern Dir* dirstat(char*); extern Dir* dirstat(char*);
@ -810,6 +820,10 @@ extern long dirreadall(int, Dir**);
extern void rerrstr(char*, uint); extern void rerrstr(char*, uint);
extern char* sysname(void); extern char* sysname(void);
extern void werrstr(char*, ...); 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 */ /* external names that we don't want to step on */
#ifndef NOPLAN9DEFINES #ifndef NOPLAN9DEFINES

View file

@ -79,8 +79,8 @@ int nbsendul(Channel *c, unsigned long v);
int proccreate(void (*f)(void *arg), void *arg, unsigned int stacksize); int proccreate(void (*f)(void *arg), void *arg, unsigned int stacksize);
int procrfork(void (*f)(void *arg), void *arg, unsigned int stacksize, int flag); int procrfork(void (*f)(void *arg), void *arg, unsigned int stacksize, int flag);
void** procdata(void); void** procdata(void);
void procexec(Channel *, char *, char *[]); void procexec(Channel *, int[3], char *, char *[]);
void procexecl(Channel *, char *, ...); void procexecl(Channel *, int[3], char *, ...);
int recv(Channel *c, void *v); int recv(Channel *c, void *v);
void* recvp(Channel *c); void* recvp(Channel *c);
unsigned long recvul(Channel *c); unsigned long recvul(Channel *c);

View file

@ -38,7 +38,8 @@ data matches '[a-zA-Z¡-
data matches '([a-zA-Z¡-￿0-9_\-./]+)\.(jpe?g|JPE?G|gif|GIF|tiff?|TIFF?|ppm|bit)' data matches '([a-zA-Z¡-￿0-9_\-./]+)\.(jpe?g|JPE?G|gif|GIF|tiff?|TIFF?|ppm|bit)'
arg isfile $0 arg isfile $0
plumb to image 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 # postscript/pdf/dvi go to page but not over the a plumb port
# the port is here for reference but is unused # the port is here for reference but is unused
@ -47,7 +48,8 @@ data matches '[a-zA-Z¡-
data matches '([a-zA-Z¡-￿0-9_\-./]+)\.(ps|PS|eps|EPS|pdf|PDF|dvi|DVI)' data matches '([a-zA-Z¡-￿0-9_\-./]+)\.(ps|PS|eps|EPS|pdf|PDF|dvi|DVI)'
arg isfile $0 arg isfile $0
plumb to postscript 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 # existing files, possibly tagged by line number, go to editor
type is text type is text
@ -56,8 +58,7 @@ arg isfile $1
data set $file data set $file
attr add addr=$3 attr add addr=$3
plumb to edit plumb to edit
plumb start /usr/local/plan9/bin/B $file:$3 plumb client $editor
# plumb client window $editor
# .h files are looked up in /usr/include and passed to edit # .h files are looked up in /usr/include and passed to edit
type is text type is text
@ -66,8 +67,7 @@ arg isfile /usr/include/$1
data set $file data set $file
attr add addr=$3 attr add addr=$3
plumb to edit plumb to edit
plumb start /usr/local/plan9/bin/B $file:$3 plumb client $editor
# plumb client window $editor
# .h files are looked up in /usr/local/include and passed to edit # .h files are looked up in /usr/local/include and passed to edit
type is text type is text
@ -76,8 +76,7 @@ arg isfile /usr/local/include/$1
data set $file data set $file
attr add addr=$3 attr add addr=$3
plumb to edit plumb to edit
plumb start /usr/local/plan9/bin/B $file:$3 plumb client $editor
# plumb client window $editor
# .h files are looked up in /usr/local/plan9/include and passed to edit # .h files are looked up in /usr/local/plan9/include and passed to edit
type is text type is text
@ -86,8 +85,7 @@ arg isfile /usr/local/plan9/include/$1
data set $file data set $file
attr add addr=$3 attr add addr=$3
plumb to edit plumb to edit
plumb start /usr/local/plan9/bin/B $file:$3 plumb client $editor
# plumb client window $editor
# .m files are looked up in /sys/module and passed to edit # .m files are looked up in /sys/module and passed to edit
type is text type is text
@ -96,8 +94,7 @@ arg isfile /sys/module/$1
data set $file data set $file
attr add addr=$3 attr add addr=$3
plumb to edit 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 # faces -> new mail window for message
type is text 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 # start rule for images without known suffixes
dst is image dst is image
arg isfile $data
plumb to image plumb to image
plumb client page -wi plumb start qiv -t $data
# start rule for postscript without known suffixes # start rule for postscript without known suffixes
dst is postscript dst is postscript
arg isfile $data arg isfile $data
plumb start page -w $data plumb start gv $data
type is text type is text
data matches 'Local (.*)' data matches 'Local (.*)'

View file

@ -11,7 +11,9 @@ usage(void)
fprint(2, "usage: 9p [-a address] cmd args...\n"); fprint(2, "usage: 9p [-a address] cmd args...\n");
fprint(2, "possible cmds:\n"); fprint(2, "possible cmds:\n");
fprint(2, " read name\n"); fprint(2, " read name\n");
fprint(2, " readfd name\n");
fprint(2, " write name\n"); fprint(2, " write name\n");
fprint(2, " writefd name\n");
fprint(2, " stat name\n"); fprint(2, " stat name\n");
// fprint(2, " ls name\n"); // fprint(2, " ls name\n");
fprint(2, "without -a, name elem/path means /path on server unix!$ns/elem\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 xread(int, char**);
void xwrite(int, char**); void xwrite(int, char**);
void xreadfd(int, char**);
void xwritefd(int, char**);
void xstat(int, char**); void xstat(int, char**);
void xls(int, char**); void xls(int, char**);
@ -29,6 +33,8 @@ struct {
} cmds[] = { } cmds[] = {
"read", xread, "read", xread,
"write", xwrite, "write", xwrite,
"readfd", xreadfd,
"writefd", xwritefd,
"stat", xstat, "stat", xstat,
// "ls", xls, // "ls", xls,
}; };
@ -64,7 +70,6 @@ Fsys*
xparse(char *name, char **path) xparse(char *name, char **path)
{ {
int fd; int fd;
char *ns;
char *p; char *p;
Fsys *fs; Fsys *fs;
@ -75,22 +80,17 @@ xparse(char *name, char **path)
else else
*p++ = 0; *p++ = 0;
*path = p; *path = p;
if(*name == 0) fs = nsmount(name, "");
usage(); if(fs == nil)
ns = getenv("ns"); sysfatal("mount: %r");
if(ns == nil) }else{
sysfatal("ns not set");
addr = smprint("unix!%s/%s", ns, name);
if(addr == nil)
sysfatal("out of memory");
}else
*path = name; *path = name;
fprint(2, "dial %s...", addr);
fprint(2, "dial %s...", addr); if((fd = dial(addr, nil, nil, nil)) < 0)
if((fd = dial(addr, nil, nil, nil)) < 0) sysfatal("dial: %r");
sysfatal("dial: %r"); if((fs = fsmount(fd, "")) == nil)
if((fs = fsmount(fd)) == nil) sysfatal("fsmount: %r");
sysfatal("fsmount: %r"); }
return fs; return fs;
} }
@ -120,6 +120,15 @@ xopen(char *name, int mode)
return fid; return fid;
} }
int
xopenfd(char *name, int mode)
{
Fsys *fs;
fs = xparse(name, &name);
return fsopenfd(fs, name, mode);
}
void void
xread(int argc, char **argv) xread(int argc, char **argv)
{ {
@ -143,6 +152,29 @@ xread(int argc, char **argv)
exits(0); exits(0);
} }
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 void
xwrite(int argc, char **argv) xwrite(int argc, char **argv)
{ {
@ -167,6 +199,30 @@ xwrite(int argc, char **argv)
exits(0); exits(0);
} }
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 void
xstat(int argc, char **argv) xstat(int argc, char **argv)
{ {

View file

@ -2,6 +2,8 @@
#include <libc.h> #include <libc.h>
#include <fcall.h> #include <fcall.h>
#include <thread.h> #include <thread.h>
#include <poll.h>
#include <errno.h>
enum enum
{ {
@ -38,6 +40,7 @@ struct Msg
int ref; int ref;
int ctag; int ctag;
int tag; int tag;
int isopenfd;
Fcall tx; Fcall tx;
Fcall rx; Fcall rx;
Fid *fid; Fid *fid;
@ -52,6 +55,8 @@ struct Msg
struct Conn struct Conn
{ {
int fd; int fd;
int fdmode;
Fid *fdfid;
int nmsg; int nmsg;
int nfid; int nfid;
Channel *inc; Channel *inc;
@ -89,7 +94,7 @@ void *erealloc(void*, int);
Queue *qalloc(void); Queue *qalloc(void);
int sendq(Queue*, void*); int sendq(Queue*, void*);
void *recvq(Queue*); void *recvq(Queue*);
void selectthread(void*); void pollthread(void*);
void connthread(void*); void connthread(void*);
void connoutthread(void*); void connoutthread(void*);
void listenthread(void*); void listenthread(void*);
@ -100,6 +105,10 @@ int tlisten(char*, char*);
int taccept(int, char*); int taccept(int, char*);
int iolisten(Ioproc*, char*, char*); int iolisten(Ioproc*, char*, char*);
int ioaccept(Ioproc*, int, char*); int ioaccept(Ioproc*, int, char*);
int iorecvfd(Ioproc*, int);
int iosendfd(Ioproc*, int, int);
void mainproc(void*);
int ignorepipe(void*, char*);
void void
usage(void) usage(void)
@ -110,14 +119,13 @@ usage(void)
} }
uchar vbuf[128]; uchar vbuf[128];
extern int _threaddebuglevel;
void void
threadmain(int argc, char **argv) threadmain(int argc, char **argv)
{ {
char *file; char *file;
int n;
Fcall f;
if(verbose) fprint(2, "9pserve running\n");
ARGBEGIN{ ARGBEGIN{
default: default:
usage(); usage();
@ -142,6 +150,20 @@ threadmain(int argc, char **argv)
if((afd = announce(addr, adir)) < 0) if((afd = announce(addr, adir)) < 0)
sysfatal("announce %s: %r", addr); 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('D', dirfmt);
fmtinstall('M', dirmodefmt); fmtinstall('M', dirmodefmt);
fmtinstall('F', fcallfmt); fmtinstall('F', fcallfmt);
@ -150,10 +172,6 @@ threadmain(int argc, char **argv)
outq = qalloc(); outq = qalloc();
inq = qalloc(); inq = qalloc();
// threadcreateidle(selectthread, nil, STACK);
threadcreate(inputthread, nil, STACK);
threadcreate(outputthread, nil, STACK);
f.type = Tversion; f.type = Tversion;
f.version = "9P2000"; f.version = "9P2000";
f.msize = 8192; f.msize = 8192;
@ -165,7 +183,22 @@ threadmain(int argc, char **argv)
if(convM2S(vbuf, n, &f) != n) if(convM2S(vbuf, n, &f) != n)
sysfatal("convM2S failure"); sysfatal("convM2S failure");
if(verbose > 1) fprint(2, "* -> %F\n", &f); if(verbose > 1) fprint(2, "* -> %F\n", &f);
threadcreate(inputthread, nil, STACK);
threadcreate(outputthread, nil, STACK);
threadcreate(listenthread, 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 void
@ -178,10 +211,6 @@ listenthread(void *arg)
USED(arg); USED(arg);
for(;;){ for(;;){
c = emalloc(sizeof(Conn)); 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); c->fd = iolisten(io, adir, c->dir);
if(c->fd < 0){ if(c->fd < 0){
if(verbose) fprint(2, "listen: %r\n"); if(verbose) fprint(2, "listen: %r\n");
@ -189,13 +218,17 @@ listenthread(void *arg)
free(c); free(c);
return; 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); if(verbose) fprint(2, "incoming call on %s\n", c->dir);
threadcreate(connthread, c, STACK); threadcreate(connthread, c, STACK);
} }
} }
void void
sendmsg(Msg *m) send9pmsg(Msg *m)
{ {
int n, nn; int n, nn;
@ -226,7 +259,7 @@ err(Msg *m, char *ename)
m->rx.type = Rerror; m->rx.type = Rerror;
m->rx.ename = ename; m->rx.ename = ename;
m->rx.tag = m->tx.tag; m->rx.tag = m->tx.tag;
sendmsg(m); send9pmsg(m);
} }
void void
@ -250,7 +283,7 @@ connthread(void *arg)
c->fd = fd; c->fd = fd;
threadcreate(connoutthread, c, STACK); threadcreate(connoutthread, c, STACK);
while((m = mread9p(io, c->fd)) != nil){ 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->c = c;
m->ctag = m->tx.tag; m->ctag = m->tx.tag;
c->nmsg++; c->nmsg++;
@ -267,13 +300,13 @@ connthread(void *arg)
m->rx.msize = 8192; m->rx.msize = 8192;
m->rx.version = "9P2000"; m->rx.version = "9P2000";
m->rx.type = Rversion; m->rx.type = Rversion;
sendmsg(m); send9pmsg(m);
continue; continue;
case Tflush: case Tflush:
if((m->oldm = gethash(c->tag, m->tx.oldtag)) == nil){ if((m->oldm = gethash(c->tag, m->tx.oldtag)) == nil){
m->rx.tag = m->tx.tag; m->rx.tag = m->tx.tag;
m->rx.type = Rflush; m->rx.type = Rflush;
sendmsg(m); send9pmsg(m);
continue; continue;
} }
m->oldm->ref++; m->oldm->ref++;
@ -318,6 +351,15 @@ connthread(void *arg)
} }
m->afid->ref++; m->afid->ref++;
break; 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 Tcreate:
case Topen: case Topen:
case Tclunk: case Tclunk:
@ -363,6 +405,7 @@ connthread(void *arg)
m = msgnew(); m = msgnew();
m->internal = 1; m->internal = 1;
m->c = c; m->c = c;
c->nmsg++;
m->tx.type = Tflush; m->tx.type = Tflush;
m->tx.tag = m->tag; m->tx.tag = m->tag;
m->tx.oldtag = om->tag; m->tx.oldtag = om->tag;
@ -371,7 +414,9 @@ connthread(void *arg)
m->ref++; /* for outq */ m->ref++; /* for outq */
sendomsg(m); sendomsg(m);
recvp(c->internal); 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 = msgnew();
m->internal = 1; m->internal = 1;
m->c = c; m->c = c;
c->nmsg++;
m->tx.type = Tclunk; m->tx.type = Tclunk;
m->tx.tag = m->tag; m->tx.tag = m->tag;
m->tx.fid = f->fid; m->tx.fid = f->fid;
@ -390,7 +436,9 @@ connthread(void *arg)
m->ref++; m->ref++;
sendomsg(m); sendomsg(m);
recvp(c->internal); 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->nmsg == 0);
assert(c->nfid == 0); assert(c->nfid == 0);
close(c->fd); 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); 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 void
connoutthread(void *arg) connoutthread(void *arg)
{ {
@ -413,6 +609,9 @@ connoutthread(void *arg)
io = ioproc(); io = ioproc();
while((m = recvq(c->outq)) != nil){ while((m = recvq(c->outq)) != nil){
err = m->tx.type+1 != m->rx.type; err = m->tx.type+1 != m->rx.type;
if(!err && m->isopenfd)
if(xopenfd(m) < 0)
continue;
switch(m->tx.type){ switch(m->tx.type){
case Tflush: case Tflush:
om = m->oldm; om = m->oldm;
@ -446,7 +645,7 @@ connoutthread(void *arg)
} }
if(delhash(m->c->tag, m->ctag, m) == 0) if(delhash(m->c->tag, m->ctag, m) == 0)
msgput(m); 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); rewritehdr(&m->rx, m->rpkt);
if(mwrite9p(io, c->fd, m->rpkt) < 0) if(mwrite9p(io, c->fd, m->rpkt) < 0)
if(verbose) fprint(2, "write error: %r\n"); if(verbose) fprint(2, "write error: %r\n");
@ -473,6 +672,8 @@ outputthread(void *arg)
msgput(m); msgput(m);
} }
closeioproc(io); closeioproc(io);
fprint(2, "output eof\n");
threadexitsall(0);
} }
void void
@ -483,6 +684,7 @@ inputthread(void *arg)
Msg *m; Msg *m;
Ioproc *io; Ioproc *io;
if(verbose) fprint(2, "input thread\n");
io = ioproc(); io = ioproc();
USED(arg); USED(arg);
while((pkt = read9ppkt(io, 0)) != nil){ while((pkt = read9ppkt(io, 0)) != nil){
@ -514,6 +716,8 @@ inputthread(void *arg)
sendq(m->c->outq, m); sendq(m->c->outq, m);
} }
closeioproc(io); closeioproc(io);
fprint(2, "input eof\n");
threadexitsall(0);
} }
void* void*
@ -626,15 +830,20 @@ msgput(Msg *m)
m->c->nmsg--; m->c->nmsg--;
m->c = nil; m->c = nil;
fidput(m->fid); fidput(m->fid);
fidput(m->afid);
fidput(m->newfid);
free(m->tpkt);
free(m->rpkt);
m->fid = nil; m->fid = nil;
fidput(m->afid);
m->afid = nil; m->afid = nil;
fidput(m->newfid);
m->newfid = nil; m->newfid = nil;
free(m->tpkt);
m->tpkt = nil; m->tpkt = nil;
free(m->rpkt);
m->rpkt = nil; 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; m->next = freemsg;
freemsg = m; freemsg = m;
} }
@ -649,6 +858,7 @@ msgget(int n)
m = msgtab[n]; m = msgtab[n];
if(m->ref == 0) if(m->ref == 0)
return nil; return nil;
if(verbose) fprint(2, "msgget %d = %p\n", n, m);
m->ref++; m->ref++;
return m; return m;
} }
@ -768,6 +978,12 @@ read9ppkt(Ioproc *io, int fd)
free(pkt); free(pkt);
return nil; 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; return pkt;
} }
@ -795,7 +1011,7 @@ mread9p(Ioproc *io, int fd)
int int
mwrite9p(Ioproc *io, int fd, uchar *pkt) mwrite9p(Ioproc *io, int fd, uchar *pkt)
{ {
int n; int n, nfd;
n = GBIT32(pkt); n = GBIT32(pkt);
if(verbose > 2) fprint(2, "write %d %d %.*H\n", fd, n, n, 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"); fprint(2, "write error: %r\n");
return -1; 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; return 0;
} }
@ -871,42 +1094,212 @@ rewritehdr(Fcall *f, uchar *pkt)
#ifdef _LIB9_H_ #ifdef _LIB9_H_
/* unix select-based polling */ /* 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*
ioproc(void) 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 long
ioread(Ioproc *io, int fd, void *v, long n) ioread(Ioproc *io, int fd, void *v, long n)
{ {
long r;
USED(io); USED(io);
xxx; noblock(fd);
while((r=read(fd, v, n)) < 0 && errno == EWOULDBLOCK)
rwait(io, fd);
return r;
}
long
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);
noblock(fd);
while((r=write(fd, v, n)) < 0 && errno == EWOULDBLOCK)
wwait(io, fd);
return r;
} }
long long
iowrite(Ioproc *io, int fd, void *v, long n) iowrite(Ioproc *io, int fd, void *v, long n)
{ {
USED(io); long tot, m;
uchar *u;
xxx; 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 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); 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 int
ioaccept(Ioproc *io, int fd, char *dir) ioaccept(Ioproc *io, int fd, char *dir)
{ {
int r;
USED(io); USED(io);
xxx; noblock(fd);
while((r=accept(fd, dir)) < 0 && errno == EWOULDBLOCK)
rwait(io, fd);
return r;
} }
#else #else

View file

@ -1212,7 +1212,6 @@ rcstart(int fd[2], int argc, char **argv)
argv[1] = "-i"; argv[1] = "-i";
argv[2] = 0; argv[2] = 0;
} }
/* /*
* fd0 is slave (tty), fd1 is master (pty) * fd0 is slave (tty), fd1 is master (pty)
*/ */
@ -1222,7 +1221,7 @@ rcstart(int fd[2], int argc, char **argv)
switch(pid = fork()) { switch(pid = fork()) {
case 0: case 0:
putenv("TERM=9term"); putenv("TERM", "9term");
close(fd[1]); close(fd[1]);
setsid(); setsid();
// tcsetpgrp(0, pid); // tcsetpgrp(0, pid);
@ -1238,6 +1237,7 @@ rcstart(int fd[2], int argc, char **argv)
dup(sfd, 2); dup(sfd, 2);
system("stty tabs -onlcr -echo"); system("stty tabs -onlcr -echo");
execvp(argv[0], argv); execvp(argv[0], argv);
fprint(2, "exec %s failed: %r\n", argv[0]);
_exits("oops"); _exits("oops");
break; break;
case -1: case -1:
@ -1388,9 +1388,7 @@ scroll(int but)
void void
plumbstart(void) plumbstart(void)
{ {
char buf[256]; if((plumbfd = plumbopen("send", OWRITE)) < 0)
snprint(buf, sizeof buf, "%s/mnt/plumb", getenv("HOME"));
if((plumbfd = plumbopen(buf, OWRITE)) < 0)
fatal("plumbopen"); fatal("plumbopen");
} }

View file

@ -9,5 +9,5 @@ OFILES=\
<$PLAN9/src/mkone <$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

View file

@ -21,6 +21,7 @@ typedef void* pointer;
#define NE 3 #define NE 3
#define length(p) ((p)->wt-(p)->beg) #define length(p) ((p)->wt-(p)->beg)
#define rewind(p) (p)->rd=(p)->beg #define rewind(p) (p)->rd=(p)->beg
#undef create
#define create(p) (p)->rd = (p)->wt = (p)->beg #define create(p) (p)->rd = (p)->wt = (p)->beg
#define fsfile(p) (p)->rd = (p)->wt #define fsfile(p) (p)->rd = (p)->wt
#define truncate(p) (p)->wt = (p)->rd #define truncate(p) (p)->wt = (p)->rd

View file

@ -59,18 +59,13 @@ void
main(int argc, char **argv) main(int argc, char **argv)
{ {
int i, cmd, kflag; int i, cmd, kflag;
char *line, *p, *root; char *line, *p;
Binit(&binbuf, 0, OREAD); Binit(&binbuf, 0, OREAD);
Binit(&boutbuf, 1, OWRITE); Binit(&boutbuf, 1, OWRITE);
kflag = 0; kflag = 0;
line = 0; line = 0;
dict = 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++){ for(i=0; dicts[i].name; i++){
if(access(dicts[i].path, 0)>=0 && access(dicts[i].indexpath, 0)>=0){ 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); bdict = Bopen(dict->path, OREAD);
if(!bdict) { if(!bdict) {
err("can't open dictionary %s/%s", root, dict->path); err("can't open dictionary %s", dict->path);
exits("nodict"); exits("nodict");
} }
bindex = Bopen(dict->indexpath, OREAD); bindex = Bopen(dict->indexpath, OREAD);
if(!bindex) { if(!bindex) {
err("can't open index %s/%s", root, dict->indexpath); err("can't open index %s", dict->indexpath);
exits("noindex"); exits("noindex");
} }
indextop = Bseek(bindex, 0L, 2); indextop = Bseek(bindex, 0L, 2);

View file

@ -5,160 +5,160 @@
Dict dicts[] = { Dict dicts[] = {
{"oed", "Oxford English Dictionary, 2nd Ed.", {"oed", "Oxford English Dictionary, 2nd Ed.",
"dict/oed2", "dict/oed2index", "#9/dict/oed2", "#9/dict/oed2index",
oednextoff, oedprintentry, oedprintkey}, oednextoff, oedprintentry, oedprintkey},
{"ahd", "American Heritage Dictionary, 2nd College Ed.", {"ahd", "American Heritage Dictionary, 2nd College Ed.",
"ahd/DICT.DB", "ahd/index", "ahd/DICT.DB", "ahd/index",
ahdnextoff, ahdprintentry, ahdprintkey}, ahdnextoff, ahdprintentry, ahdprintkey},
{"pgw", "Project Gutenberg Webster Dictionary", {"pgw", "Project Gutenberg Webster Dictionary",
"dict/pgw", "dict/pgwindex", "#9/dict/pgw", "#9/dict/pgwindex",
pgwnextoff, pgwprintentry, pgwprintkey}, pgwnextoff, pgwprintentry, pgwprintkey},
{"thesaurus", "Collins Thesaurus", {"thesaurus", "Collins Thesaurus",
"dict/thesaurus", "dict/thesindex", "#9/dict/thesaurus", "#9/dict/thesindex",
thesnextoff, thesprintentry, thesprintkey}, thesnextoff, thesprintentry, thesprintkey},
{"ce", "Gendai Chinese->English", {"ce", "Gendai Chinese->English",
"dict/world/sansdata/sandic24.dat", "#9/dict/world/sansdata/sandic24.dat",
"dict/world/sansdata/ceindex", "#9/dict/world/sansdata/ceindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"ceh", "Gendai Chinese->English (Hanzi index)", {"ceh", "Gendai Chinese->English (Hanzi index)",
"dict/world/sansdata/sandic24.dat", "#9/dict/world/sansdata/sandic24.dat",
"dict/world/sansdata/cehindex", "#9/dict/world/sansdata/cehindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"ec", "Gendai English->Chinese", {"ec", "Gendai English->Chinese",
"dict/world/sansdata/sandic24.dat", "#9/dict/world/sansdata/sandic24.dat",
"dict/world/sansdata/ecindex", "#9/dict/world/sansdata/ecindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"dae", "Gyldendal Danish->English", {"dae", "Gyldendal Danish->English",
"dict/world/gylddata/sandic30.dat", "#9/dict/world/gylddata/sandic30.dat",
"dict/world/gylddata/daeindex", "#9/dict/world/gylddata/daeindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"eda", "Gyldendal English->Danish", {"eda", "Gyldendal English->Danish",
"dict/world/gylddata/sandic29.dat", "#9/dict/world/gylddata/sandic29.dat",
"dict/world/gylddata/edaindex", "#9/dict/world/gylddata/edaindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"due", "Wolters-Noordhoff Dutch->English", {"due", "Wolters-Noordhoff Dutch->English",
"dict/world/woltdata/sandic07.dat", "#9/dict/world/woltdata/sandic07.dat",
"dict/world/woltdata/deindex", "#9/dict/world/woltdata/deindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"edu", "Wolters-Noordhoff English->Dutch", {"edu", "Wolters-Noordhoff English->Dutch",
"dict/world/woltdata/sandic06.dat", "#9/dict/world/woltdata/sandic06.dat",
"dict/world/woltdata/edindex", "#9/dict/world/woltdata/edindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"fie", "WSOY Finnish->English", {"fie", "WSOY Finnish->English",
"dict/world/werndata/sandic32.dat", "#9/dict/world/werndata/sandic32.dat",
"dict/world/werndata/fieindex", "#9/dict/world/werndata/fieindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"efi", "WSOY English->Finnish", {"efi", "WSOY English->Finnish",
"dict/world/werndata/sandic31.dat", "#9/dict/world/werndata/sandic31.dat",
"dict/world/werndata/efiindex", "#9/dict/world/werndata/efiindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"fe", "Collins French->English", {"fe", "Collins French->English",
"dict/fe", "dict/feindex", "#9/dict/fe", "#9/dict/feindex",
pcollnextoff, pcollprintentry, pcollprintkey}, pcollnextoff, pcollprintentry, pcollprintkey},
{"ef", "Collins English->French", {"ef", "Collins English->French",
"dict/ef", "dict/efindex", "#9/dict/ef", "#9/dict/efindex",
pcollnextoff, pcollprintentry, pcollprintkey}, pcollnextoff, pcollprintentry, pcollprintkey},
{"ge", "Collins German->English", {"ge", "Collins German->English",
"dict/ge", "dict/geindex", "#9/dict/ge", "#9/dict/geindex",
pcollgnextoff, pcollgprintentry, pcollgprintkey}, pcollgnextoff, pcollgprintentry, pcollgprintkey},
{"eg", "Collins English->German", {"eg", "Collins English->German",
"dict/eg", "dict/egindex", "#9/dict/eg", "#9/dict/egindex",
pcollgnextoff, pcollgprintentry, pcollgprintkey}, pcollgnextoff, pcollgprintentry, pcollgprintkey},
{"ie", "Collins Italian->English", {"ie", "Collins Italian->English",
"dict/ie", "dict/ieindex", "#9/dict/ie", "#9/dict/ieindex",
pcollnextoff, pcollprintentry, pcollprintkey}, pcollnextoff, pcollprintentry, pcollprintkey},
{"ei", "Collins English->Italian", {"ei", "Collins English->Italian",
"dict/ei", "dict/eiindex", "#9/dict/ei", "#9/dict/eiindex",
pcollnextoff, pcollprintentry, pcollprintkey}, pcollnextoff, pcollprintentry, pcollprintkey},
{"je", "Sanshusha Japanese->English", {"je", "Sanshusha Japanese->English",
"dict/world/sansdata/sandic18.dat", "#9/dict/world/sansdata/sandic18.dat",
"dict/world/sansdata/jeindex", "#9/dict/world/sansdata/jeindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"jek", "Sanshusha Japanese->English (Kanji index)", {"jek", "Sanshusha Japanese->English (Kanji index)",
"dict/world/sansdata/sandic18.dat", "#9/dict/world/sansdata/sandic18.dat",
"dict/world/sansdata/jekindex", "#9/dict/world/sansdata/jekindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"ej", "Sanshusha English->Japanese", {"ej", "Sanshusha English->Japanese",
"dict/world/sansdata/sandic18.dat", "#9/dict/world/sansdata/sandic18.dat",
"dict/world/sansdata/ejindex", "#9/dict/world/sansdata/ejindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"tjeg", "Sanshusha technical Japanese->English,German", {"tjeg", "Sanshusha technical Japanese->English,German",
"dict/world/sansdata/sandic16.dat", "#9/dict/world/sansdata/sandic16.dat",
"dict/world/sansdata/tjegindex", "#9/dict/world/sansdata/tjegindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"tjegk", "Sanshusha technical Japanese->English,German (Kanji index)", {"tjegk", "Sanshusha technical Japanese->English,German (Kanji index)",
"dict/world/sansdata/sandic16.dat", "#9/dict/world/sansdata/sandic16.dat",
"dict/world/sansdata/tjegkindex", "#9/dict/world/sansdata/tjegkindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"tegj", "Sanshusha technical English->German,Japanese", {"tegj", "Sanshusha technical English->German,Japanese",
"dict/world/sansdata/sandic16.dat", "#9/dict/world/sansdata/sandic16.dat",
"dict/world/sansdata/tegjindex", "#9/dict/world/sansdata/tegjindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"tgje", "Sanshusha technical German->Japanese,English", {"tgje", "Sanshusha technical German->Japanese,English",
"dict/world/sansdata/sandic16.dat", "#9/dict/world/sansdata/sandic16.dat",
"dict/world/sansdata/tgjeindex", "#9/dict/world/sansdata/tgjeindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"ne", "Kunnskapforlaget Norwegian->English", {"ne", "Kunnskapforlaget Norwegian->English",
"dict/world/kunndata/sandic28.dat", "#9/dict/world/kunndata/sandic28.dat",
"dict/world/kunndata/neindex", "#9/dict/world/kunndata/neindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"en", "Kunnskapforlaget English->Norwegian", {"en", "Kunnskapforlaget English->Norwegian",
"dict/world/kunndata/sandic27.dat", "#9/dict/world/kunndata/sandic27.dat",
"dict/world/kunndata/enindex", "#9/dict/world/kunndata/enindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"re", "Leon Ungier Russian->English", {"re", "Leon Ungier Russian->English",
"dict/re", "dict/reindex", "#9/dict/re", "#9/dict/reindex",
simplenextoff, simpleprintentry, simpleprintkey}, simplenextoff, simpleprintentry, simpleprintkey},
{"er", "Leon Ungier English->Russian", {"er", "Leon Ungier English->Russian",
"dict/re", "dict/erindex", "#9/dict/re", "#9/dict/erindex",
simplenextoff, simpleprintentry, simpleprintkey}, simplenextoff, simpleprintentry, simpleprintkey},
{"se", "Collins Spanish->English", {"se", "Collins Spanish->English",
"dict/se", "dict/seindex", "#9/dict/se", "#9/dict/seindex",
pcollnextoff, pcollprintentry, pcollprintkey}, pcollnextoff, pcollprintentry, pcollprintkey},
{"es", "Collins English->Spanish", {"es", "Collins English->Spanish",
"dict/es", "dict/esindex", "#9/dict/es", "#9/dict/esindex",
pcollnextoff, pcollprintentry, pcollprintkey}, pcollnextoff, pcollprintentry, pcollprintkey},
{"swe", "Esselte Studium Swedish->English", {"swe", "Esselte Studium Swedish->English",
"dict/world/essedata/sandic34.dat", "#9/dict/world/essedata/sandic34.dat",
"dict/world/essedata/sweindex", "#9/dict/world/essedata/sweindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"esw", "Esselte Studium English->Swedish", {"esw", "Esselte Studium English->Swedish",
"dict/world/essedata/sandic33.dat", "#9/dict/world/essedata/sandic33.dat",
"dict/world/essedata/eswindex", "#9/dict/world/essedata/eswindex",
worldnextoff, worldprintentry, worldprintkey}, worldnextoff, worldprintentry, worldprintkey},
{"movie", "Movies -- by title", {"movie", "Movies -- by title",
"movie/data", "dict/movtindex", "movie/data", "#9/dict/movtindex",
movienextoff, movieprintentry, movieprintkey}, movienextoff, movieprintentry, movieprintkey},
{"moviea", "Movies -- by actor", {"moviea", "Movies -- by actor",
"movie/data", "dict/movaindex", "movie/data", "#9/dict/movaindex",
movienextoff, movieprintentry, movieprintkey}, movienextoff, movieprintentry, movieprintkey},
{"movied", "Movies -- by director", {"movied", "Movies -- by director",
"movie/data", "dict/movdindex", "movie/data", "#9/dict/movdindex",
movienextoff, movieprintentry, movieprintkey}, movienextoff, movieprintentry, movieprintkey},
{"slang", "English Slang", {"slang", "English Slang",
"dict/slang", "dict/slangindex", "#9/dict/slang", "#9/dict/slangindex",
slangnextoff, slangprintentry, slangprintkey}, slangnextoff, slangprintentry, slangprintkey},
{"robert", "Robert Électronique", {"robert", "Robert Électronique",
"dict/robert/_pointers", "dict/robert/_index", "#9/dict/robert/_pointers", "#9/dict/robert/_index",
robertnextoff, robertindexentry, robertprintkey}, robertnextoff, robertindexentry, robertprintkey},
{"robertv", "Robert Électronique - formes des verbes", {"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}, robertnextflex, robertflexentry, robertprintkey},
{0, 0, 0, 0, 0} {0, 0, 0, 0, 0}

View file

@ -2,11 +2,11 @@ PLAN9=../..
<$PLAN9/src/mkhdr <$PLAN9/src/mkhdr
TARG=`ls *.c | sed 's/\.c//'` 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 <$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"` DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "$BUGGERED"`
<$PLAN9/src/mkdirs <$PLAN9/src/mkdirs

View file

@ -3,14 +3,13 @@
#include <bio.h> #include <bio.h>
#include <regexp.h> #include <regexp.h>
#include <thread.h> #include <thread.h>
#include <auth.h>
#include <fcall.h> #include <fcall.h>
#include <plumb.h> #include <plumb.h>
#include "plumber.h" #include "plumber.h"
enum enum
{ {
Stack = 8*1024 Stack = 32*1024
}; };
typedef struct Dirtab Dirtab; typedef struct Dirtab Dirtab;
@ -73,13 +72,12 @@ struct Holdq
struct /* needed because incref() doesn't return value */ struct /* needed because incref() doesn't return value */
{ {
Lock; Lock lk;
int ref; int ref;
} rulesref; } rulesref;
enum enum
{ {
DEBUG = 0,
NDIR = 50, NDIR = 50,
Nhash = 16, Nhash = 16,
@ -99,13 +97,10 @@ static Dirtab dir[NDIR] =
static int ndir = NQID; static int ndir = NQID;
static int srvfd; static int srvfd;
static int srvclosefd; /* rock for end of pipe to close */
static int clockfd;
static int clock; static int clock;
static Fid *fids[Nhash]; static Fid *fids[Nhash];
static QLock readlock; static QLock readlock;
static QLock queue; static QLock queue;
static char srvfile[128];
static int messagesize = 8192+IOHDRSZ; /* good start */ static int messagesize = 8192+IOHDRSZ; /* good start */
static void fsysproc(void*); static void fsysproc(void*);
@ -183,54 +178,35 @@ addport(char *port)
static ulong static ulong
getclock(void) getclock(void)
{ {
char buf[32]; return time(0);
seek(clockfd, 0, 0);
read(clockfd, buf, sizeof buf);
return atoi(buf);
} }
void void
startfsys(void) startfsys(void)
{ {
int p[2], fd; int p[2];
fmtinstall('F', fcallfmt); fmtinstall('F', fcallfmt);
clockfd = open("/dev/time", OREAD|OCEXEC);
clock = getclock(); clock = getclock();
if(pipe(p) < 0) if(pipe(p) < 0)
error("can't create pipe: %r"); error("can't create pipe: %r");
/* 0 will be server end, 1 will be client end */ /* 0 will be server end, 1 will be client end */
srvfd = p[0]; srvfd = p[0];
srvclosefd = p[1]; if(post9pservice(p[1], "plumb") < 0)
sprint(srvfile, "/srv/plumb.%s.%d", user, getpid()); sysfatal("post9pservice plumb: %r");
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");
close(p[1]); close(p[1]);
proccreate(fsysproc, nil, Stack);
} }
static void static void
fsysproc(void*) fsysproc(void *v)
{ {
int n; int n;
Fcall *t; Fcall *t;
Fid *f; Fid *f;
uchar *buf; uchar *buf;
close(srvclosefd); USED(v);
srvclosefd = -1;
t = nil; t = nil;
for(;;){ for(;;){
buf = malloc(messagesize); /* avoid memset of emalloc */ buf = malloc(messagesize); /* avoid memset of emalloc */
@ -250,7 +226,7 @@ fsysproc(void*)
t = emalloc(sizeof(Fcall)); t = emalloc(sizeof(Fcall));
if(convM2S(buf, n, t) != n) if(convM2S(buf, n, t) != n)
error("convert error in convM2S"); error("convert error in convM2S");
if(DEBUG) if(debug)
fprint(2, "<= %F\n", t); fprint(2, "<= %F\n", t);
if(fcall[t->type] == nil) if(fcall[t->type] == nil)
fsysrespond(t, buf, Ebadfcall); fsysrespond(t, buf, Ebadfcall);
@ -281,7 +257,7 @@ fsysrespond(Fcall *t, uchar *buf, char *err)
error("convert error in convS2M"); error("convert error in convS2M");
if(write(srvfd, buf, n) != n) if(write(srvfd, buf, n) != n)
error("write error in respond"); error("write error in respond");
if(DEBUG) if(debug)
fprint(2, "=> %F\n", t); fprint(2, "=> %F\n", t);
free(buf); free(buf);
} }
@ -555,8 +531,10 @@ dispose(Fcall *t, uchar *buf, Plumbmsg *m, Ruleset *rs, Exec *e)
} }
static Fcall* static Fcall*
fsysversion(Fcall *t, uchar *buf, Fid*) fsysversion(Fcall *t, uchar *buf, Fid *fid)
{ {
USED(fid);
if(t->msize < 256){ if(t->msize < 256){
fsysrespond(t, buf, "version: message size too small"); fsysrespond(t, buf, "version: message size too small");
return t; return t;
@ -574,8 +552,9 @@ fsysversion(Fcall *t, uchar *buf, Fid*)
} }
static Fcall* static Fcall*
fsysauth(Fcall *t, uchar *buf, Fid*) fsysauth(Fcall *t, uchar *buf, Fid *fid)
{ {
USED(fid);
fsysrespond(t, buf, "plumber: authentication not required"); fsysrespond(t, buf, "plumber: authentication not required");
return t; return t;
} }
@ -605,10 +584,11 @@ fsysattach(Fcall *t, uchar *buf, Fid *f)
} }
static Fcall* static Fcall*
fsysflush(Fcall *t, uchar *buf, Fid*) fsysflush(Fcall *t, uchar *buf, Fid *fid)
{ {
int i; int i;
USED(fid);
qlock(&queue); qlock(&queue);
for(i=NQID; i<ndir; i++) for(i=NQID; i<ndir; i++)
flushqueue(&dir[i], t->oldtag); flushqueue(&dir[i], t->oldtag);
@ -729,14 +709,14 @@ fsysopen(Fcall *t, uchar *buf, Fid *f)
if(((f->dir->perm&~(DMDIR|DMAPPEND))&m) != m) if(((f->dir->perm&~(DMDIR|DMAPPEND))&m) != m)
goto Deny; goto Deny;
if(f->qid.path==Qrules && (mode==OWRITE || mode==ORDWR)){ if(f->qid.path==Qrules && (mode==OWRITE || mode==ORDWR)){
lock(&rulesref); lock(&rulesref.lk);
if(rulesref.ref++ != 0){ if(rulesref.ref++ != 0){
rulesref.ref--; rulesref.ref--;
unlock(&rulesref); unlock(&rulesref.lk);
fsysrespond(t, buf, Einuse); fsysrespond(t, buf, Einuse);
return t; return t;
} }
unlock(&rulesref); unlock(&rulesref.lk);
} }
if(clearrules){ if(clearrules){
writerules(nil, 0); writerules(nil, 0);
@ -761,8 +741,9 @@ fsysopen(Fcall *t, uchar *buf, Fid *f)
} }
static Fcall* static Fcall*
fsyscreate(Fcall *t, uchar *buf, Fid*) fsyscreate(Fcall *t, uchar *buf, Fid *fid)
{ {
USED(fid);
fsysrespond(t, buf, Eperm); fsysrespond(t, buf, Eperm);
return t; return t;
} }
@ -916,15 +897,17 @@ fsysstat(Fcall *t, uchar *buf, Fid *f)
} }
static Fcall* static Fcall*
fsyswstat(Fcall *t, uchar *buf, Fid*) fsyswstat(Fcall *t, uchar *buf, Fid *fid)
{ {
USED(fid);
fsysrespond(t, buf, Eperm); fsysrespond(t, buf, Eperm);
return t; return t;
} }
static Fcall* static Fcall*
fsysremove(Fcall *t, uchar *buf, Fid*) fsysremove(Fcall *t, uchar *buf, Fid *fid)
{ {
USED(fid);
fsysrespond(t, buf, Eperm); fsysrespond(t, buf, Eperm);
return t; return t;
} }
@ -945,9 +928,9 @@ fsysclunk(Fcall *t, uchar *buf, Fid *f)
* unless last write ended with a blank line * unless last write ended with a blank line
*/ */
writerules(nil, 0); writerules(nil, 0);
lock(&rulesref); lock(&rulesref.lk);
rulesref.ref--; rulesref.ref--;
unlock(&rulesref); unlock(&rulesref.lk);
} }
prev = nil; prev = nil;
for(p=d->fopen; p; p=p->nextopen){ for(p=d->fopen; p; p=p->nextopen){

View file

@ -6,6 +6,7 @@
#include <plumb.h> #include <plumb.h>
#include "plumber.h" #include "plumber.h"
/*
static char* static char*
nonnil(char *s) nonnil(char *s)
{ {
@ -13,6 +14,7 @@ nonnil(char *s)
return ""; return "";
return s; return s;
} }
*/
int int
verbis(int obj, Plumbmsg *m, Rule *r) verbis(int obj, Plumbmsg *m, Rule *r)
@ -44,10 +46,10 @@ setvar(Resub rs[10], char *match[10])
free(match[i]); free(match[i]);
match[i] = nil; match[i] = nil;
} }
for(i=0; i<10 && rs[i].sp!=nil; i++){ for(i=0; i<10 && rs[i].s.sp!=nil; i++){
n = rs[i].ep-rs[i].sp; n = rs[i].e.ep-rs[i].s.sp;
match[i] = emalloc(n+1); match[i] = emalloc(n+1);
memmove(match[i], rs[i].sp, n); memmove(match[i], rs[i].s.sp, n);
match[i][n] = '\0'; match[i][n] = '\0';
} }
} }
@ -66,7 +68,7 @@ clickmatch(Reprog *re, char *text, Resub rs[10], int click)
for(i=0; i<=click; i++){ for(i=0; i<=click; i++){
memset(rs, 0, 10*sizeof(Resub)); memset(rs, 0, 10*sizeof(Resub));
if(regexec(re, text+i, rs, 10)) 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 1;
} }
return 0; return 0;
@ -94,8 +96,8 @@ verbmatches(int obj, Plumbmsg *m, Rule *r, Exec *e)
} }
if(!clickmatch(r->regex, m->data, rs, atoi(clickval))) if(!clickmatch(r->regex, m->data, rs, atoi(clickval)))
break; break;
p0 = rs[0].sp - m->data; p0 = rs[0].s.sp - m->data;
p1 = rs[0].ep - m->data; p1 = rs[0].e.ep - m->data;
if(e->p0 >=0 && !(p0==e->p0 && p1==e->p1)) if(e->p0 >=0 && !(p0==e->p0 && p1==e->p1))
break; break;
e->clearclick = 1; e->clearclick = 1;
@ -120,7 +122,7 @@ verbmatches(int obj, Plumbmsg *m, Rule *r, Exec *e)
/* must match full text */ /* must match full text */
if(ntext < 0) if(ntext < 0)
ntext = strlen(alltext); 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; break;
setvar(rs, e->match); setvar(rs, e->match);
return 1; return 1;
@ -389,7 +391,7 @@ enum
{ {
NARGS = 100, NARGS = 100,
NARGCHAR = 8*1024, 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 */ /* 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 void
execproc(void *v) execproc(void *v)
{ {
int fd[3];
char **av; char **av;
char buf[1024], *args[NARGS+1], argc[NARGCHAR]; char *args[NARGS+1], argc[NARGCHAR];
rfork(RFFDG); fd[0] = open("/dev/null", OREAD);
close(0); fd[1] = dup(1, -1);
open("/dev/null", OREAD); fd[2] = dup(2, -1);
av = v; av = v;
stackargv(av, args, argc); stackargv(av, args, argc);
free(av); free(av);
procexec(nil, args[0], args); procexec(nil, fd, 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);
threadexits("can't exec"); threadexits("can't exec");
} }

View file

@ -1,10 +1,9 @@
</$objtype/mkfile PLAN9=../../..
<$PLAN9/src/mkhdr
TARG=plumber plumb TARG=plumber plumb
<$PLAN9/src/mkmany
BIN=/$objtype/bin
</sys/src/cmd/mkmany
PLUMBER=plumber.$O fsys.$O match.$O rules.$O PLUMBER=plumber.$O fsys.$O match.$O rules.$O
PLUMB=plumb.$O PLUMB=plumb.$O
@ -15,6 +14,4 @@ $PLUMB: $HFILES
$O.plumb: $PLUMB $O.plumb: $PLUMB
$O.plumber: $PLUMBER $O.plumber: $PLUMBER
syms:V: LDFLAGS=$LDFLAGS -lplumb -lfs -lmux -lthread -lregexp9 -l9 -lbio -lfmt -lutf
8c -a plumber.c >syms
8c -aa fsys.c match.c rules.c >>syms

View file

@ -3,10 +3,10 @@
#include <regexp.h> #include <regexp.h>
#include <thread.h> #include <thread.h>
#include <plumb.h> #include <plumb.h>
#include <auth.h>
#include <fcall.h> #include <fcall.h>
#include "plumber.h" #include "plumber.h"
int debug;
char *plumbfile; char *plumbfile;
char *user; char *user;
char *home; char *home;
@ -47,13 +47,18 @@ threadmain(int argc, char *argv[])
progname = "plumber"; progname = "plumber";
ARGBEGIN{ ARGBEGIN{
case 'd':
debug = 1;
break;
case 'p': case 'p':
plumbfile = ARGF(); plumbfile = ARGF();
break; break;
}ARGEND }ARGEND
user = getenv("user"); user = getuser();
home = getenv("home"); home = getenv("home");
if(home == nil)
home = getenv("HOME");
if(user==nil || home==nil) if(user==nil || home==nil)
error("can't initialize $user or $home: %r"); error("can't initialize $user or $home: %r");
if(plumbfile == nil){ if(plumbfile == nil){

View file

@ -91,3 +91,4 @@ jmp_buf parsejmp;
char *lasterror; char *lasterror;
char **ports; char **ports;
int nports; int nports;
int debug;

View file

@ -143,7 +143,7 @@ char*
getline(void) getline(void)
{ {
static int n = 0; static int n = 0;
static char *s, *incl; static char *s /*, *incl*/;
int c, i; int c, i;
i = 0; i = 0;
@ -414,7 +414,7 @@ include(char *s)
t = args[1]; t = args[1];
fd = open(t, OREAD); fd = open(t, OREAD);
if(fd<0 && t[0]!='/' && strncmp(t, "./", 2)!=0 && strncmp(t, "../", 3)!=0){ 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; t = buf;
fd = open(t, OREAD); fd = open(t, OREAD);
} }

View file

@ -27,6 +27,8 @@ char *syssigname[]={
char* char*
Rcmain(void) Rcmain(void)
{ {
return "#9/rcmain";
/*
static char buf[256]; static char buf[256];
char *root; char *root;
@ -35,9 +37,10 @@ Rcmain(void)
root = "/usr/local/plan9"; root = "/usr/local/plan9";
snprint(buf, sizeof buf, "%s/rcmain", root); snprint(buf, sizeof buf, "%s/rcmain", root);
return buf; return buf;
*/
} }
char Fdprefix[]="/dev/fd/"; char Fdprefix[]="#d/";
void execfinit(void); void execfinit(void);
void execbind(void); void execbind(void);
void execmount(void); void execmount(void);

View file

@ -214,92 +214,4 @@ erealloc(void *p, ulong n)
return p; 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

View file

@ -13,8 +13,8 @@
#define SETBIT(a,i) ((a)[(i)>>5] |= (1<<((i)&037))) #define SETBIT(a,i) ((a)[(i)>>5] |= (1<<((i)&037)))
#define NWORDS(n) (((n)+32)/32) #define NWORDS(n) (((n)+32)/32)
#define PARSER "lib/yaccpar" #define PARSER "#9/lib/yaccpar"
#define PARSERS "lib/yaccpars" #define PARSERS "#9/lib/yaccpars"
#define TEMPNAME "y.tmp.XXXXXX" #define TEMPNAME "y.tmp.XXXXXX"
#define ACTNAME "y.acts.XXXXXX" #define ACTNAME "y.acts.XXXXXX"
#define OFILE "tab.c" #define OFILE "tab.c"
@ -398,19 +398,10 @@ void
others(void) others(void)
{ {
int c, i, j; int c, i, j;
char *s, *root;
root = getenv("PLAN9"); finput = Bopen(parser, OREAD);
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);
if(finput == 0) if(finput == 0)
error("cannot find parser %s", s); error("cannot find parser %s", parser);
free(s);
warray("yyr1", levprd, nprod); warray("yyr1", levprd, nprod);
aryfil(temp1, nprod, 0); aryfil(temp1, nprod, 0);
PLOOP(1, i) PLOOP(1, i)

View file

@ -5,13 +5,14 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/un.h> #include <sys/un.h>
#include <errno.h>
#undef sun #undef sun
#define sun sockun #define sun sockun
extern int _p9dialparse(char*, char**, char**, u32int*, int*); extern int _p9dialparse(char*, char**, char**, u32int*, int*);
static int int
getfd(char *dir) _p9netfd(char *dir)
{ {
int fd; int fd;
@ -83,7 +84,6 @@ p9announce(char *addr, char *dir)
if(proto == SOCK_STREAM){ if(proto == SOCK_STREAM){
listen(s, 8); listen(s, 8);
putfd(dir, s); putfd(dir, s);
print("announce dir: %s\n", dir);
} }
return s; return s;
@ -95,9 +95,21 @@ Unix:
return -1; return -1;
sn = sizeof sun; sn = sizeof sun;
if(bind(s, (struct sockaddr*)&sun, sizeof sun) < 0){ 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); close(s);
return -1; return -1;
} }
Success:
listen(s, 8); listen(s, 8);
putfd(dir, s); putfd(dir, s);
return s; return s;
@ -108,18 +120,15 @@ p9listen(char *dir, char *newdir)
{ {
int fd; int fd;
if((fd = getfd(dir)) < 0){ if((fd = _p9netfd(dir)) < 0){
werrstr("bad 'directory' in listen: %s", dir); werrstr("bad 'directory' in listen: %s", dir);
return -1; return -1;
} }
print("accept %d", fd);
if((fd = accept(fd, nil, nil)) < 0) if((fd = accept(fd, nil, nil)) < 0)
return -1; return -1;
print(" -> %d\n", fd);
putfd(newdir, fd); putfd(newdir, fd);
print("listen dir: %s\n", newdir);
return fd; return fd;
} }
@ -128,7 +137,7 @@ p9accept(int cfd, char *dir)
{ {
int fd; int fd;
if((fd = getfd(dir)) < 0){ if((fd = _p9netfd(dir)) < 0){
werrstr("bad 'directory' in accept"); werrstr("bad 'directory' in accept");
return -1; return -1;
} }

View file

@ -45,6 +45,7 @@ static struct {
#endif #endif
SIGUSR1, "sys: usr1", SIGUSR1, "sys: usr1",
SIGUSR2, "sys: usr2", SIGUSR2, "sys: usr2",
SIGPIPE, "sys: write on closed pipe",
}; };
char* char*

View file

@ -138,6 +138,7 @@ convM2S(uchar *ap, uint nap, Fcall *f)
break; break;
case Topen: case Topen:
case Topenfd:
if(p+BIT32SZ+BIT8SZ > ep) if(p+BIT32SZ+BIT8SZ > ep)
return 0; return 0;
f->fid = GBIT32(p); f->fid = GBIT32(p);
@ -260,6 +261,7 @@ convM2S(uchar *ap, uint nap, Fcall *f)
break; break;
case Ropen: case Ropen:
case Ropenfd:
case Rcreate: case Rcreate:
p = gqid(p, ep, &f->qid); p = gqid(p, ep, &f->qid);
if(p == nil) if(p == nil)
@ -268,6 +270,12 @@ convM2S(uchar *ap, uint nap, Fcall *f)
return 0; return 0;
f->iounit = GBIT32(p); f->iounit = GBIT32(p);
p += BIT32SZ; p += BIT32SZ;
if(f->type == Ropenfd){
if(p+BIT32SZ > ep)
return 0;
f->unixfd = GBIT32(p);
p += BIT32SZ;
}
break; break;
case Rread: case Rread:

View file

@ -92,6 +92,7 @@ sizeS2M(Fcall *f)
break; break;
case Topen: case Topen:
case Topenfd:
n += BIT32SZ; n += BIT32SZ;
n += BIT8SZ; n += BIT8SZ;
break; break;
@ -164,6 +165,12 @@ sizeS2M(Fcall *f)
n += BIT32SZ; n += BIT32SZ;
break; break;
case Ropenfd:
n += QIDSZ;
n += BIT32SZ;
n += BIT32SZ;
break;
case Rread: case Rread:
n += BIT32SZ; n += BIT32SZ;
n += f->count; n += f->count;
@ -257,6 +264,7 @@ convS2M(Fcall *f, uchar *ap, uint nap)
break; break;
case Topen: case Topen:
case Topenfd:
PBIT32(p, f->fid); PBIT32(p, f->fid);
p += BIT32SZ; p += BIT32SZ;
PBIT8(p, f->mode); PBIT8(p, f->mode);
@ -347,9 +355,14 @@ convS2M(Fcall *f, uchar *ap, uint nap)
case Ropen: case Ropen:
case Rcreate: case Rcreate:
case Ropenfd:
p = pqid(p, &f->qid); p = pqid(p, &f->qid);
PBIT32(p, f->iounit); PBIT32(p, f->iounit);
p += BIT32SZ; p += BIT32SZ;
if(f->type == Ropenfd){
PBIT32(p, f->unixfd);
p += BIT32SZ;
}
break; break;
case Rread: case Rread:

View file

@ -1,8 +1,54 @@
#include <u.h> #include <u.h>
#define NOPLAN9DEFINES
#include <libc.h> #include <libc.h>
#include <sys/stat.h>
extern char *_p9translate(char*);
int 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;
} }

View file

@ -74,9 +74,16 @@ fcallfmt(Fmt *fmt)
seprint(buf, e, "Topen tag %ud fid %ud mode %d", tag, fid, f->mode); seprint(buf, e, "Topen tag %ud fid %ud mode %d", tag, fid, f->mode);
break; break;
case Ropen: 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); f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
break; 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 */ 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); seprint(buf, e, "Tcreate tag %ud fid %ud name %s perm %M mode %d", tag, fid, f->name, (ulong)f->perm, f->mode);
break; break;

View file

@ -13,3 +13,15 @@ p9getenv(char *s)
return strdup(t); 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;
}

View file

@ -8,6 +8,8 @@ OFILES=\
_p9dialparse.$O\ _p9dialparse.$O\
_p9dir.$O\ _p9dir.$O\
_p9proc.$O\ _p9proc.$O\
_p9translate.$O\
access.$O\
announce.$O\ announce.$O\
argv0.$O\ argv0.$O\
atexit.$O\ atexit.$O\
@ -40,11 +42,13 @@ OFILES=\
getcallerpc-$OBJTYPE.$O\ getcallerpc-$OBJTYPE.$O\
getenv.$O\ getenv.$O\
getfields.$O\ getfields.$O\
getns.$O\
getuser.$O\ getuser.$O\
getwd.$O\ getwd.$O\
jmp.$O\ jmp.$O\
lock.$O\ lock.$O\
main.$O\ main.$O\
malloc.$O\
malloctag.$O\ malloctag.$O\
mallocz.$O\ mallocz.$O\
nan.$O\ nan.$O\
@ -53,13 +57,18 @@ OFILES=\
notify.$O\ notify.$O\
nrand.$O\ nrand.$O\
nulldir.$O\ nulldir.$O\
open.$O\
pipe.$O\
post9p.$O\
postnote.$O\ postnote.$O\
qlock.$O\ qlock.$O\
quote.$O\ quote.$O\
read9pmsg.$O\
readn.$O\ readn.$O\
rendez-$SYSNAME.$O\ rendez-$SYSNAME.$O\
rfork.$O\ rfork.$O\
seek.$O\ seek.$O\
sendfd.$O\
sleep.$O\ sleep.$O\
strecpy.$O\ strecpy.$O\
sysfatal.$O\ sysfatal.$O\

View file

@ -19,7 +19,7 @@ static int sigs[] = {
#endif #endif
SIGFPE, SIGFPE,
SIGBUS, SIGBUS,
SIGSEGV, /* SIGSEGV, */
SIGSYS, SIGSYS,
SIGPIPE, SIGPIPE,
SIGALRM, SIGALRM,

View file

@ -9,7 +9,7 @@ p9rfork(int flags)
if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){ if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){
/* check other flags before we commit */ /* check other flags before we commit */
flags &= ~(RFPROC|RFFDG); flags &= ~(RFPROC|RFFDG);
if(flags & ~(RFNOTEG)){ if(flags & ~(RFNOTEG|RFNAMEG)){
werrstr("unknown flags %08ux in rfork", flags); werrstr("unknown flags %08ux in rfork", flags);
return -1; return -1;
} }
@ -17,11 +17,14 @@ p9rfork(int flags)
if(pid != 0) if(pid != 0)
return pid; return pid;
} }
if(flags&RFPROC){ if(flags&RFPROC){
werrstr("cannot use rfork to fork -- use ffork"); werrstr("cannot use rfork for shared memory -- use ffork");
return -1; return -1;
} }
if(flags&RFNAMEG){
/* XXX set $NAMESPACE to a new directory */
flags &= ~RFNAMEG;
}
if(flags&RFNOTEG){ if(flags&RFNOTEG){
setpgid(0, getpid()); setpgid(0, getpid());
flags &= ~RFNOTEG; flags &= ~RFNOTEG;

View file

@ -9,21 +9,15 @@ openfont(Display *d, char *name)
{ {
Font *fnt; Font *fnt;
int fd, i, n; int fd, i, n;
char *buf, *nambuf, *root; char *buf, *nambuf;
nambuf = 0; nambuf = 0;
fd = open(name, OREAD); fd = open(name, OREAD);
if(fd < 0 && strncmp(name, "/lib/font/bit/", 14) == 0){ if(fd < 0 && strncmp(name, "/lib/font/bit/", 14) == 0){
root = getenv("PLAN9"); nambuf = smprint("#9/font/%s", name+14);
if(root == nil)
return 0;
nambuf = malloc(strlen(root)+5+strlen(name+13)+1);
if(nambuf == nil) if(nambuf == nil)
return 0; return 0;
strcpy(nambuf, root);
strcat(nambuf, "/font");
strcat(nambuf, name+13);
if((fd = open(nambuf, OREAD)) < 0){ if((fd = open(nambuf, OREAD)) < 0){
free(nambuf); free(nambuf);
return 0; return 0;

View file

@ -10,7 +10,7 @@
* Allocate a Memimage with an optional pixmap backing on the X server. * Allocate a Memimage with an optional pixmap backing on the X server.
*/ */
Memimage* Memimage*
xallocmemimage(Rectangle r, u32int chan, int pixmap) _xallocmemimage(Rectangle r, u32int chan, int pixmap)
{ {
int d, offset; int d, offset;
Memimage *m; Memimage *m;
@ -95,7 +95,7 @@ xallocmemimage(Rectangle r, u32int chan, int pixmap)
Memimage* Memimage*
allocmemimage(Rectangle r, u32int chan) allocmemimage(Rectangle r, u32int chan)
{ {
return xallocmemimage(r, chan, PMundef); return _xallocmemimage(r, chan, PMundef);
} }
void void

View file

@ -13,7 +13,7 @@ cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata)
n = _cloadmemimage(i, r, data, ndata); n = _cloadmemimage(i, r, data, ndata);
if(n > 0 && i->X) if(n > 0 && i->X)
xputxdata(i, r); _xputxdata(i, r);
return n; return n;
} }

View file

@ -24,11 +24,11 @@ memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp,
/* only fetch dst data if we need it */ /* only fetch dst data if we need it */
if((par->state&(Simplemask|Fullmask)) != (Simplemask|Fullmask)) if((par->state&(Simplemask|Fullmask)) != (Simplemask|Fullmask))
xgetxdata(dst, par->r); _xgetxdata(dst, par->r);
/* always fetch source and mask */ /* always fetch source and mask */
xgetxdata(src, par->sr); _xgetxdata(src, par->sr);
xgetxdata(mask, par->mr); _xgetxdata(mask, par->mr);
/* now can run memimagedraw on the in-memory bits */ /* now can run memimagedraw on the in-memory bits */
_memimagedraw(par); _memimagedraw(par);
@ -37,7 +37,7 @@ memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp,
return; return;
/* put bits back on x server */ /* put bits back on x server */
xputxdata(dst, par->r); _xputxdata(dst, par->r);
} }
static int static int
@ -66,7 +66,7 @@ xdraw(Memdrawparam *par)
*/ */
m = Simplesrc|Simplemask|Fullmask; m = Simplesrc|Simplemask|Fullmask;
if((state&m) == m){ if((state&m) == m){
xfillcolor(dst, r, par->sdval); _xfillcolor(dst, r, par->sdval);
// xdirtyxdata(dst, r); // xdirtyxdata(dst, r);
return 1; return 1;
} }

View file

@ -48,7 +48,7 @@ eread(ulong keys, Event *e)
xmask |= MouseMask|StructureNotifyMask; xmask |= MouseMask|StructureNotifyMask;
if(keys&Ekeyboard){ if(keys&Ekeyboard){
xmask |= KeyPressMask; xmask |= KeyPressMask;
if((r = xtoplan9kbd(nil)) >= 0){ if((r = _xtoplan9kbd(nil)) >= 0){
e->kbdc = r; e->kbdc = r;
return Ekeyboard; return Ekeyboard;
} }
@ -60,24 +60,24 @@ again:
switch(xevent.type){ switch(xevent.type){
case Expose: case Expose:
xexpose(&xevent, _x.display); _xexpose(&xevent, _x.display);
goto again; goto again;
case DestroyNotify: case DestroyNotify:
if(xdestroy(&xevent, _x.display)) if(_xdestroy(&xevent, _x.display))
postnote(PNGROUP, getpgrp(), "hangup"); postnote(PNGROUP, getpgrp(), "hangup");
goto again; goto again;
case ConfigureNotify: case ConfigureNotify:
if(xconfigure(&xevent, _x.display)) if(_xconfigure(&xevent, _x.display))
eresized(1); eresized(1);
goto again; goto again;
case ButtonPress: case ButtonPress:
case ButtonRelease: case ButtonRelease:
case MotionNotify: case MotionNotify:
if(xtoplan9mouse(_x.display, &xevent, &e->mouse) < 0) if(_xtoplan9mouse(_x.display, &xevent, &e->mouse) < 0)
goto again; goto again;
return Emouse; return Emouse;
case KeyPress: case KeyPress:
e->kbdc = xtoplan9kbd(&xevent); e->kbdc = _xtoplan9kbd(&xevent);
if(e->kbdc == -1) if(e->kbdc == -1)
goto again; goto again;
return Ekeyboard; return Ekeyboard;
@ -136,7 +136,7 @@ ecanmouse(void)
eflush(); eflush();
again: again:
if(XCheckWindowEvent(_x.display, _x.drawable, MouseMask, &xe)){ if(XCheckWindowEvent(_x.display, _x.drawable, MouseMask, &xe)){
if(xtoplan9mouse(_x.display, &xe, &m) < 0) if(_xtoplan9mouse(_x.display, &xe, &m) < 0)
goto again; goto again;
XPutBackEvent(_x.display, &xe); XPutBackEvent(_x.display, &xe);
return 1; return 1;
@ -151,13 +151,13 @@ ecankbd(void)
int r; int r;
eflush(); eflush();
if((r = xtoplan9kbd(nil)) >= 0){ if((r = _xtoplan9kbd(nil)) >= 0){
xtoplan9kbd((XEvent*)-1); _xtoplan9kbd((XEvent*)-1);
return 1; return 1;
} }
again: again:
if(XCheckWindowEvent(_x.display, _x.drawable, KeyPressMask, &xe)){ if(XCheckWindowEvent(_x.display, _x.drawable, KeyPressMask, &xe)){
if(xtoplan9kbd(&xe) == -1) if(_xtoplan9kbd(&xe) == -1)
goto again; goto again;
XPutBackEvent(_x.display, &xe); XPutBackEvent(_x.display, &xe);
return 1; return 1;
@ -168,12 +168,12 @@ again:
void void
emoveto(Point p) emoveto(Point p)
{ {
xmoveto(p); _xmoveto(p);
} }
void void
esetcursor(Cursor *c) esetcursor(Cursor *c)
{ {
xsetcursor(c); _xsetcursor(c);
} }

View file

@ -13,13 +13,13 @@ memfillcolor(Memimage *m, u32int val)
if(m->X == nil) if(m->X == nil)
return; return;
if((val & 0xFF) == 0xFF) /* full alpha */ if((val & 0xFF) == 0xFF) /* full alpha */
xfillcolor(m, m->r, _rgbatoimg(m, val)); _xfillcolor(m, m->r, _rgbatoimg(m, val));
else else
xputxdata(m, m->r); _xputxdata(m, m->r);
} }
void void
xfillcolor(Memimage *m, Rectangle r, u32int v) _xfillcolor(Memimage *m, Rectangle r, u32int v)
{ {
Point p; Point p;
Xmem *xm; Xmem *xm;

View file

@ -16,7 +16,7 @@ addrect(Rectangle *rp, Rectangle r)
} }
XImage* XImage*
xgetxdata(Memimage *m, Rectangle r) _xgetxdata(Memimage *m, Rectangle r)
{ {
int x, y; int x, y;
uchar *p; uchar *p;
@ -55,7 +55,7 @@ xgetxdata(Memimage *m, Rectangle r)
} }
void void
xputxdata(Memimage *m, Rectangle r) _xputxdata(Memimage *m, Rectangle r)
{ {
int offset, x, y; int offset, x, y;
uchar *p; uchar *p;
@ -97,7 +97,7 @@ xputxdata(Memimage *m, Rectangle r)
} }
void void
xdirtyxdata(Memimage *m, Rectangle r) _xdirtyxdata(Memimage *m, Rectangle r)
{ {
Xmem *xm; Xmem *xm;

View file

@ -359,7 +359,7 @@ xattach(char *label)
_x.screenr = r; _x.screenr = r;
_x.screenpm = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth); _x.screenpm = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth);
_x.nextscreenpm = _x.screenpm; _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. * Allocate some useful graphics contexts for the future.
@ -651,7 +651,7 @@ flushmemscreen(Rectangle r)
} }
void void
xexpose(XEvent *e, XDisplay *xd) _xexpose(XEvent *e, XDisplay *xd)
{ {
XExposeEvent *xe; XExposeEvent *xe;
Rectangle r; Rectangle r;
@ -673,7 +673,7 @@ xexpose(XEvent *e, XDisplay *xd)
} }
int int
xdestroy(XEvent *e, XDisplay *xd) _xdestroy(XEvent *e, XDisplay *xd)
{ {
XDestroyWindowEvent *xe; XDestroyWindowEvent *xe;
@ -686,7 +686,7 @@ xdestroy(XEvent *e, XDisplay *xd)
} }
int int
xconfigure(XEvent *e, XDisplay *xd) _xconfigure(XEvent *e, XDisplay *xd)
{ {
Rectangle r; Rectangle r;
XConfigureEvent *xe = (XConfigureEvent*)e; XConfigureEvent *xe = (XConfigureEvent*)e;
@ -719,7 +719,7 @@ xreplacescreenimage(void)
return 0; return 0;
pixmap = XCreatePixmap(_x.display, _x.drawable, Dx(r), Dy(r), _x.depth); 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) if(_x.nextscreenpm != _x.screenpm)
XFreePixmap(_x.display, _x.nextscreenpm); XFreePixmap(_x.display, _x.nextscreenpm);
_x.nextscreenpm = pixmap; _x.nextscreenpm = pixmap;

View file

@ -12,7 +12,7 @@
#include "x11-memdraw.h" #include "x11-memdraw.h"
static int static int
_xtoplan9kbd(XEvent *e) __xtoplan9kbd(XEvent *e)
{ {
int ind, k, md; int ind, k, md;
@ -125,7 +125,7 @@ xtoplan9latin1(XEvent *e)
int n; int n;
int r; int r;
r = _xtoplan9kbd(e); r = __xtoplan9kbd(e);
if(r < 0) if(r < 0)
return nil; return nil;
if(alting){ if(alting){
@ -156,7 +156,7 @@ xtoplan9latin1(XEvent *e)
} }
int int
xtoplan9kbd(XEvent *e) _xtoplan9kbd(XEvent *e)
{ {
static Rune *r; static Rune *r;
@ -173,7 +173,7 @@ xtoplan9kbd(XEvent *e)
} }
int int
xtoplan9mouse(XDisplay *xd, XEvent *e, Mouse *m) _xtoplan9mouse(XDisplay *xd, XEvent *e, Mouse *m)
{ {
int s; int s;
XButtonEvent *be; XButtonEvent *be;
@ -260,7 +260,7 @@ xtoplan9mouse(XDisplay *xd, XEvent *e, Mouse *m)
} }
void void
xmoveto(Point p) _xmoveto(Point p)
{ {
XWarpPointer(_x.display, None, _x.drawable, 0, 0, 0, 0, p.x, p.y); XWarpPointer(_x.display, None, _x.drawable, 0, 0, 0, 0, p.x, p.y);
XFlush(_x.display); XFlush(_x.display);
@ -296,7 +296,7 @@ xcursorarrow(void)
void void
xsetcursor(Cursor *c) _xsetcursor(Cursor *c)
{ {
XColor fg, bg; XColor fg, bg;
XCursor xc; XCursor xc;
@ -335,7 +335,7 @@ struct {
} clip; } clip;
char* char*
xgetsnarf(XDisplay *xd) _xgetsnarf(XDisplay *xd)
{ {
uchar *data, *xdata; uchar *data, *xdata;
Atom clipboard, type, prop; Atom clipboard, type, prop;
@ -420,7 +420,7 @@ out:
} }
void void
xputsnarf(XDisplay *xd, char *data) _xputsnarf(XDisplay *xd, char *data)
{ {
XButtonEvent e; XButtonEvent e;
@ -445,7 +445,7 @@ xputsnarf(XDisplay *xd, char *data)
} }
int int
xselect(XEvent *e, XDisplay *xd) _xselect(XEvent *e, XDisplay *xd)
{ {
char *name; char *name;
XEvent r; XEvent r;
@ -493,12 +493,12 @@ if(0) fprint(2, "xselect target=%d requestor=%d property=%d selection=%d\n",
void void
putsnarf(char *data) putsnarf(char *data)
{ {
xputsnarf(_x.snarfcon, data); _xputsnarf(_x.snarfcon, data);
} }
char* char*
getsnarf(void) getsnarf(void)
{ {
return xgetsnarf(_x.snarfcon); return _xgetsnarf(_x.snarfcon);
} }

View file

@ -46,12 +46,12 @@ _ioproc(void *arg)
XWindowEvent(_x.kbdcon, _x.drawable, KeyPressMask, &xevent); XWindowEvent(_x.kbdcon, _x.drawable, KeyPressMask, &xevent);
switch(xevent.type){ switch(xevent.type){
case KeyPress: case KeyPress:
i = xtoplan9kbd(&xevent); i = _xtoplan9kbd(&xevent);
if(i == -1) if(i == -1)
continue; continue;
r = i; r = i;
send(kc->c, &r); send(kc->c, &r);
while((i=xtoplan9kbd(nil)) >= 0){ while((i=_xtoplan9kbd(nil)) >= 0){
r = i; r = i;
send(kc->c, &r); send(kc->c, &r);
} }

View file

@ -13,7 +13,7 @@ loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata)
n = _loadmemimage(i, r, data, ndata); n = _loadmemimage(i, r, data, ndata);
if(n > 0 && i->X) if(n > 0 && i->X)
xputxdata(i, r); _xputxdata(i, r);
return n; return n;
} }

View file

@ -76,26 +76,26 @@ struct Xprivate {
extern Xprivate _x; extern Xprivate _x;
extern Memimage *xallocmemimage(Rectangle, u32int, int); extern Memimage *_xallocmemimage(Rectangle, u32int, int);
extern XImage *xallocxdata(Memimage*, Rectangle); extern XImage *_xallocxdata(Memimage*, Rectangle);
extern void xdirtyxdata(Memimage*, Rectangle); extern void _xdirtyxdata(Memimage*, Rectangle);
extern void xfillcolor(Memimage*, Rectangle, u32int); extern void _xfillcolor(Memimage*, Rectangle, u32int);
extern void xfreexdata(Memimage*); extern void _xfreexdata(Memimage*);
extern XImage *xgetxdata(Memimage*, Rectangle); extern XImage *_xgetxdata(Memimage*, Rectangle);
extern void xputxdata(Memimage*, Rectangle); extern void _xputxdata(Memimage*, Rectangle);
extern void _initdisplaymemimage(Display*, Memimage*); extern void _initdisplaymemimage(Display*, Memimage*);
struct Mouse; struct Mouse;
extern int xtoplan9mouse(XDisplay*, XEvent*, struct Mouse*); extern int _xtoplan9mouse(XDisplay*, XEvent*, struct Mouse*);
extern int xtoplan9kbd(XEvent*); extern int _xtoplan9kbd(XEvent*);
extern void xexpose(XEvent*, XDisplay*); extern void _xexpose(XEvent*, XDisplay*);
extern int xselect(XEvent*, XDisplay*); extern int _xselect(XEvent*, XDisplay*);
extern int xconfigure(XEvent*, XDisplay*); extern int _xconfigure(XEvent*, XDisplay*);
extern int xdestroy(XEvent*, XDisplay*); extern int _xdestroy(XEvent*, XDisplay*);
extern void flushmemscreen(Rectangle); extern void _flushmemscreen(Rectangle);
extern void xmoveto(Point); extern void _xmoveto(Point);
struct Cursor; struct Cursor;
extern void xsetcursor(struct Cursor*); extern void _xsetcursor(struct Cursor*);
#define MouseMask (\ #define MouseMask (\
ButtonPressMask|\ ButtonPressMask|\

View file

@ -11,7 +11,7 @@
void void
moveto(Mousectl *m, Point pt) moveto(Mousectl *m, Point pt)
{ {
xmoveto(pt); _xmoveto(pt);
} }
void void
@ -64,10 +64,10 @@ _ioproc(void *arg)
XNextEvent(_x.mousecon, &xevent); XNextEvent(_x.mousecon, &xevent);
switch(xevent.type){ switch(xevent.type){
case Expose: case Expose:
xexpose(&xevent, _x.mousecon); _xexpose(&xevent, _x.mousecon);
continue; continue;
case DestroyNotify: case DestroyNotify:
if(xdestroy(&xevent, _x.mousecon)){ if(_xdestroy(&xevent, _x.mousecon)){
/* drain it before sending */ /* drain it before sending */
/* apps that care can notice we sent a 0 */ /* apps that care can notice we sent a 0 */
/* otherwise we'll have getwindow send SIGHUP */ /* otherwise we'll have getwindow send SIGHUP */
@ -77,16 +77,16 @@ _ioproc(void *arg)
} }
continue; continue;
case ConfigureNotify: case ConfigureNotify:
if(xconfigure(&xevent, _x.mousecon)) if(_xconfigure(&xevent, _x.mousecon))
nbsend(mc->resizec, &one); nbsend(mc->resizec, &one);
continue; continue;
case SelectionRequest: case SelectionRequest:
xselect(&xevent, _x.mousecon); _xselect(&xevent, _x.mousecon);
continue; continue;
case ButtonPress: case ButtonPress:
case ButtonRelease: case ButtonRelease:
case MotionNotify: case MotionNotify:
if(xtoplan9mouse(_x.mousecon, &xevent, &m) < 0) if(_xtoplan9mouse(_x.mousecon, &xevent, &m) < 0)
continue; continue;
send(mc->c, &m); send(mc->c, &m);
/* /*
@ -117,6 +117,6 @@ initmouse(char *file, Image *i)
void void
setcursor(Mousectl *mc, Cursor *c) setcursor(Mousectl *mc, Cursor *c)
{ {
xsetcursor(c); _xsetcursor(c);
} }

View file

@ -10,7 +10,7 @@ u32int
pixelbits(Memimage *m, Point p) pixelbits(Memimage *m, Point p)
{ {
if(m->X) 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); return _pixelbits(m, p);
} }

View file

@ -10,7 +10,7 @@ int
unloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) unloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata)
{ {
if(i->X) if(i->X)
xgetxdata(i, r); _xgetxdata(i, r);
return _unloadmemimage(i, r, data, ndata); return _unloadmemimage(i, r, data, ndata);
} }

View file

@ -50,7 +50,7 @@ fsroot(Fsys *fs)
} }
Fsys* Fsys*
fsmount(int fd) fsmount(int fd, char *aname)
{ {
int n; int n;
char *user; char *user;
@ -62,13 +62,14 @@ fsmount(int fd)
strcpy(fs->version, "9P2000"); strcpy(fs->version, "9P2000");
if((n = fsversion(fs, 8192, fs->version, sizeof fs->version)) < 0){ if((n = fsversion(fs, 8192, fs->version, sizeof fs->version)) < 0){
Error: Error:
fs->fd = -1;
fsunmount(fs); fsunmount(fs);
return nil; return nil;
} }
fs->msize = n; fs->msize = n;
user = getuser(); user = getuser();
if((fs->root = fsattach(fs, nil, getuser(), "")) == nil) if((fs->root = fsattach(fs, nil, getuser(), aname)) == nil)
goto Error; goto Error;
return fs; return fs;
} }
@ -76,6 +77,8 @@ fsmount(int fd)
void void
fsunmount(Fsys *fs) fsunmount(Fsys *fs)
{ {
fsclose(fs->root);
fs->root = nil;
_fsdecref(fs); _fsdecref(fs);
} }
@ -85,7 +88,9 @@ _fsdecref(Fsys *fs)
Fid *f, *next; Fid *f, *next;
qlock(&fs->lk); 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); close(fs->fd);
for(f=fs->freefid; f; f=next){ for(f=fs->freefid; f; f=next){
next = f->next; next = f->next;
@ -103,6 +108,7 @@ fsversion(Fsys *fs, int msize, char *version, int nversion)
void *freep; void *freep;
Fcall tx, rx; Fcall tx, rx;
tx.tag = 0;
tx.type = Tversion; tx.type = Tversion;
tx.version = version; tx.version = version;
tx.msize = msize; tx.msize = msize;
@ -120,9 +126,13 @@ fsattach(Fsys *fs, Fid *afid, char *user, char *aname)
Fcall tx, rx; Fcall tx, rx;
Fid *fid; Fid *fid;
if(aname == nil)
aname = "";
if((fid = _fsgetfid(fs)) == nil) if((fid = _fsgetfid(fs)) == nil)
return nil; return nil;
tx.tag = 0;
tx.type = Tattach; tx.type = Tattach;
tx.afid = afid ? afid->fid : NOFID; tx.afid = afid ? afid->fid : NOFID;
tx.fid = fid->fid; tx.fid = fid->fid;
@ -145,12 +155,11 @@ fsrpc(Fsys *fs, Fcall *tx, Fcall *rx, void **freep)
n = sizeS2M(tx); n = sizeS2M(tx);
tpkt = malloc(n); tpkt = malloc(n);
fprint(2, "tpkt %p\n", tpkt);
if(freep) if(freep)
*freep = nil; *freep = nil;
if(tpkt == nil) if(tpkt == nil)
return -1; return -1;
fprint(2, "<- %F\n", tx); //fprint(2, "<- %F\n", tx);
nn = convS2M(tx, tpkt, n); nn = convS2M(tx, tpkt, n);
if(nn != n){ if(nn != n){
free(tpkt); free(tpkt);
@ -159,20 +168,18 @@ fprint(2, "tpkt %p\n", tpkt);
return -1; return -1;
} }
rpkt = muxrpc(&fs->mux, tpkt); rpkt = muxrpc(&fs->mux, tpkt);
fprint(2, "tpkt %p\n", tpkt);
free(tpkt); free(tpkt);
fprint(2, "tpkt freed\n");
if(rpkt == nil) if(rpkt == nil)
return -1; return -1;
n = GBIT32((uchar*)rpkt); n = GBIT32((uchar*)rpkt);
nn = convM2S(rpkt, n, rx); nn = convM2S(rpkt, n, rx);
if(nn != n){ if(nn != n){
free(rpkt); free(rpkt);
werrstr("libfs: convM2S packet size mismatch"); werrstr("libfs: convM2S packet size mismatch %d %d", n, nn);
fprint(2, "%r\n"); fprint(2, "%r\n");
return -1; return -1;
} }
fprint(2, "-> %F\n", rx); //fprint(2, "-> %F\n", rx);
if(rx->type == Rerror){ if(rx->type == Rerror){
werrstr("%s", rx->ename); werrstr("%s", rx->ename);
free(rpkt); free(rpkt);
@ -208,13 +215,13 @@ _fsgetfid(Fsys *fs)
f[i].fid = fs->nextfid++; f[i].fid = fs->nextfid++;
f[i].next = &f[i+1]; f[i].next = &f[i+1];
f[i].fs = fs; f[i].fs = fs;
fs->ref++;
} }
f[i-1].next = nil; f[i-1].next = nil;
fs->freefid = f; fs->freefid = f;
} }
f = fs->freefid; f = fs->freefid;
fs->freefid = f->next; fs->freefid = f->next;
fs->ref++;
qunlock(&fs->lk); qunlock(&fs->lk);
return f; return f;
} }
@ -259,7 +266,7 @@ _fsrecv(Mux *mux)
{ {
uchar *pkt; uchar *pkt;
uchar buf[4]; uchar buf[4];
int n; int n, nfd;
Fsys *fs; Fsys *fs;
fs = mux->aux; fs = mux->aux;
@ -277,11 +284,13 @@ _fsrecv(Mux *mux)
free(pkt); free(pkt);
return nil; return nil;
} }
#if 0
if(pkt[4] == Ropenfd){ if(pkt[4] == Ropenfd){
/* do unix socket crap */ if((nfd=recvfd(fs->fd)) < 0){
sysfatal("no socket crap implemented"); fprint(2, "recv fd error: %r\n");
free(pkt);
return nil;
}
PBIT32(pkt+n-4, nfd);
} }
#endif
return pkt; return pkt;
} }

View file

@ -8,7 +8,9 @@ OFILES=\
create.$O\ create.$O\
dirread.$O\ dirread.$O\
fs.$O\ fs.$O\
ns.$O\
open.$O\ open.$O\
openfd.$O\
read.$O\ read.$O\
stat.$O\ stat.$O\
walk.$O\ walk.$O\

View file

@ -173,6 +173,5 @@ puttag(Mux *mux, Muxrpc *r)
mux->nwait--; mux->nwait--;
mux->freetag = i; mux->freetag = i;
rwakeup(&mux->tagrend); rwakeup(&mux->tagrend);
fprint(2, "free %p\n", r);
free(r); free(r);
} }

View file

@ -1,5 +1,7 @@
#include <u.h> #include <u.h>
#include <libc.h> #include <libc.h>
#include <fcall.h>
#include <fs.h>
#include "plumb.h" #include "plumb.h"
static char attrbuf[4096]; static char attrbuf[4096];
@ -9,35 +11,15 @@ char *home;
int int
plumbopen(char *name, int omode) plumbopen(char *name, int omode)
{ {
#if 0 Fsys *fs;
int fd, f; int fd;
char *s;
#endif
char buf[256];
if(name[0] == '/') fs = nsmount("plumb", "");
return open(name, omode); if(fs == nil)
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)
return -1; return -1;
snprint(buf, sizeof buf, "/mnt/plumb/%s", name); fd = fsopenfd(fs, name, omode);
#endif fsunmount(fs);
return open(buf, omode); return fd;
} }
static int static int

View file

@ -41,9 +41,9 @@ _xdec:
movl 4(%esp), %eax movl 4(%esp), %eax
lock decl 0(%eax) lock decl 0(%eax)
jz iszero jz iszero
movl %eax, 1 movl $1, %eax
ret ret
iszero: iszero:
movl %eax, 0 movl $0, %eax
ret ret

View file

@ -1,8 +1,7 @@
#include "threadimpl.h" #include "threadimpl.h"
Pqueue _threadpq; Pqueue _threadpq;
int _threadprocs;
int _threadmultiproc;
static int nextID(void); 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"); werrstr("cannot create procs once there is an idle thread");
return -1; return -1;
} }
_threadmultiproc = 1;
return procrfork(f, arg, stacksize, 0); return procrfork(f, arg, stacksize, 0);
} }
@ -125,11 +123,12 @@ threadcreateidle(void (*f)(void *arg), void *arg, uint stacksize)
{ {
int id; int id;
if(_threadmultiproc){ if(_threadprocs!=1){
werrstr("cannot have idle thread in multi-proc program"); werrstr("cannot have idle thread in multi-proc program");
return -1; return -1;
} }
id = newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp()); id = newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
_threaddebug(DBGSCHED, "idle is %d", id);
_threadidle(); _threadidle();
return id; return id;
} }
@ -154,6 +153,7 @@ _newproc(void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp, i
else else
*_threadpq.tail = p; *_threadpq.tail = p;
_threadpq.tail = &p->next; _threadpq.tail = &p->next;
_threadprocs++;
unlock(&_threadpq.lock); unlock(&_threadpq.lock);
return p; return p;
} }

View file

@ -3,7 +3,7 @@
#include "threadimpl.h" #include "threadimpl.h"
void void
procexec(Channel *pidc, char *prog, char *args[]) procexec(Channel *pidc, int fd[3], char *prog, char *args[])
{ {
int n; int n;
Proc *p; Proc *p;
@ -45,6 +45,7 @@ procexec(Channel *pidc, char *prog, char *args[])
assert(p->needexec==0); assert(p->needexec==0);
p->exec.prog = prog; p->exec.prog = prog;
p->exec.args = args; p->exec.args = args;
p->exec.stdfd = fd;
p->needexec = 1; p->needexec = 1;
_sched(); _sched();
@ -56,7 +57,11 @@ procexec(Channel *pidc, char *prog, char *args[])
goto Bad; goto Bad;
} }
close(p->exec.fd[0]); 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) if(pidc)
sendul(pidc, t->ret); sendul(pidc, t->ret);
@ -66,9 +71,9 @@ procexec(Channel *pidc, char *prog, char *args[])
} }
void 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 void
@ -107,10 +112,17 @@ efork(void *ve)
{ {
char buf[ERRMAX]; char buf[ERRMAX];
Execargs *e; Execargs *e;
int i;
e = ve; e = ve;
_threaddebug(DBGEXEC, "_schedexec %s -- calling execv", e->prog); _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"); _threaddebug(DBGEXEC, "_schedexec failed: %r");
rerrstr(buf, sizeof buf); rerrstr(buf, sizeof buf);
if(buf[0]=='\0') if(buf[0]=='\0')

View file

@ -3,7 +3,7 @@
#define PIPEMNT "/mnt/temp" #define PIPEMNT "/mnt/temp"
void void
procexec(Channel *pidc, char *prog, char *args[]) procexec(Channel *pidc, int fd[3], char *prog, char *args[])
{ {
int n; int n;
Proc *p; Proc *p;
@ -50,6 +50,7 @@ procexec(Channel *pidc, char *prog, char *args[])
assert(p->needexec==0); assert(p->needexec==0);
p->exec.prog = prog; p->exec.prog = prog;
p->exec.args = args; p->exec.args = args;
p->exec.stdfd = fd;
p->needexec = 1; p->needexec = 1;
_sched(); _sched();
@ -61,7 +62,11 @@ procexec(Channel *pidc, char *prog, char *args[])
goto Bad; goto Bad;
} }
close(p->exec.fd[0]); 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) if(pidc)
sendul(pidc, t->ret); sendul(pidc, t->ret);
@ -70,8 +75,8 @@ procexec(Channel *pidc, char *prog, char *args[])
} }
void 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);
} }

View file

@ -37,7 +37,7 @@ main(int argc, char **argv)
_systhreadinit(); _systhreadinit();
_qlockinit(_threadrendezvous); _qlockinit(_threadrendezvous);
_sysfatal = _threadsysfatal; _sysfatal = _threadsysfatal;
// notify(_threadnote); notify(_threadnote);
if(mainstacksize == 0) if(mainstacksize == 0)
mainstacksize = 32*1024; mainstacksize = 32*1024;
@ -98,6 +98,7 @@ _schedexit(Proc *p)
break; break;
} }
} }
_threadprocs--;
unlock(&_threadpq.lock); unlock(&_threadpq.lock);
strncpy(ex, p->exitstr, sizeof ex); strncpy(ex, p->exitstr, sizeof ex);

View file

@ -2,7 +2,6 @@
int _threadnopasser; int _threadnopasser;
#ifdef NOTDEF
#define NFN 33 #define NFN 33
#define ERRLEN 48 #define ERRLEN 48
typedef struct Note Note; typedef struct Note Note;
@ -85,7 +84,7 @@ _threadnote(void *v, char *s)
Note *n; Note *n;
_threaddebug(DBGNOTE, "Got note %s", s); _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); noted(NDFLT);
// if(_threadexitsallstatus){ // if(_threadexitsallstatus){
@ -112,7 +111,6 @@ _threadnote(void *v, char *s)
delayednotes(p, v); delayednotes(p, v);
noted(NCONT); noted(NCONT);
} }
#endif
int int
_procsplhi(void) _procsplhi(void)

View file

@ -98,17 +98,18 @@ runthread(Proc *p)
q = &p->ready; q = &p->ready;
lock(&p->readylock); lock(&p->readylock);
if(q->head == nil){ if(q->head == nil){
q->asleep = 1;
if(p->idle){ if(p->idle){
if(p->idle->state != Ready){ if(p->idle->state != Ready){
fprint(2, "everyone is asleep\n"); fprint(2, "everyone is asleep\n");
exits("everyone is asleep"); exits("everyone is asleep");
} }
unlock(&p->readylock); unlock(&p->readylock);
_threaddebug(DBGSCHED, "running idle thread", p->nthreads);
return p->idle; return p->idle;
} }
_threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads); _threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads);
q->asleep = 1;
unlock(&p->readylock); unlock(&p->readylock);
while(rendezvous((ulong)q, 0) == ~0){ while(rendezvous((ulong)q, 0) == ~0){
if(_threadexitsallstatus) if(_threadexitsallstatus)
@ -148,7 +149,7 @@ Resched:
_threaddelproc(); _threaddelproc();
_schedexit(p); _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; p->thread = t;
if(t->moribund){ if(t->moribund){
_threaddebug(DBGSCHED, "%d.%d marked to die"); _threaddebug(DBGSCHED, "%d.%d marked to die");
@ -176,8 +177,10 @@ _threadready(Thread *t)
{ {
Tqueue *q; Tqueue *q;
if(t == t->proc->idle) if(t == t->proc->idle){
_threaddebug(DBGSCHED, "idle thread is ready");
return; return;
}
assert(t->state == Ready); assert(t->state == Ready);
_threaddebug(DBGSCHED, "readying %d.%d", t->proc->pid, t->id); _threaddebug(DBGSCHED, "readying %d.%d", t->proc->pid, t->id);
@ -206,18 +209,25 @@ void
_threadidle(void) _threadidle(void)
{ {
Tqueue *q; Tqueue *q;
Thread *t; Thread *t, *idle;
Proc *p; Proc *p;
p = _threadgetproc(); p = _threadgetproc();
q = &p->ready; q = &p->ready;
lock(&p->readylock); lock(&p->readylock);
assert(q->head); assert(q->tail);
t = q->head; idle = q->tail;
q->head = t->next; if(q->head == idle){
if(q->tail == t) q->head = nil;
q->tail = 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); unlock(&p->readylock);
} }

View file

@ -105,6 +105,7 @@ struct Execargs
char *prog; char *prog;
char **args; char **args;
int fd[2]; int fd[2];
int *stdfd;
}; };
struct Proc struct Proc
@ -214,4 +215,5 @@ extern void _stackfree(void*);
extern int _threadgetpid(void); extern int _threadgetpid(void);
extern void _threadmemset(void*, int, int); extern void _threadmemset(void*, int, int);
extern void _threaddebugmemset(void*, int, int); extern void _threaddebugmemset(void*, int, int);
extern int _threadprocs;