Add support for user-level 9P servers/clients and various bug fixes to go with them.
This commit is contained in:
parent
ac244f8d28
commit
32f69c36e0
60 changed files with 965 additions and 485 deletions
6
bin/B
6
bin/B
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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*);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
26
plumb/basic
26
plumb/basic
|
|
@ -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 (.*)'
|
||||||
|
|
|
||||||
80
src/cmd/9p.c
80
src/cmd/9p.c
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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){
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
|
||||||
|
|
@ -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){
|
||||||
|
|
|
||||||
|
|
@ -91,3 +91,4 @@ jmp_buf parsejmp;
|
||||||
char *lasterror;
|
char *lasterror;
|
||||||
char **ports;
|
char **ports;
|
||||||
int nports;
|
int nports;
|
||||||
|
int debug;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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*
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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\
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ static int sigs[] = {
|
||||||
#endif
|
#endif
|
||||||
SIGFPE,
|
SIGFPE,
|
||||||
SIGBUS,
|
SIGBUS,
|
||||||
SIGSEGV,
|
/* SIGSEGV, */
|
||||||
SIGSYS,
|
SIGSYS,
|
||||||
SIGPIPE,
|
SIGPIPE,
|
||||||
SIGALRM,
|
SIGALRM,
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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|\
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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\
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
return -1;
|
||||||
}
|
fd = fsopenfd(fs, name, omode);
|
||||||
snprint(buf, sizeof buf, "%s/mnt/plumb", home);
|
fsunmount(fs);
|
||||||
#if 0
|
|
||||||
fd = open(buf, omode);
|
|
||||||
if(fd >= 0)
|
|
||||||
return fd;
|
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;
|
|
||||||
snprint(buf, sizeof buf, "/mnt/plumb/%s", name);
|
|
||||||
#endif
|
|
||||||
return open(buf, omode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue