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
|
|
@ -5,13 +5,14 @@
|
|||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
|
||||
#undef sun
|
||||
#define sun sockun
|
||||
extern int _p9dialparse(char*, char**, char**, u32int*, int*);
|
||||
|
||||
static int
|
||||
getfd(char *dir)
|
||||
int
|
||||
_p9netfd(char *dir)
|
||||
{
|
||||
int fd;
|
||||
|
||||
|
|
@ -83,7 +84,6 @@ p9announce(char *addr, char *dir)
|
|||
if(proto == SOCK_STREAM){
|
||||
listen(s, 8);
|
||||
putfd(dir, s);
|
||||
print("announce dir: %s\n", dir);
|
||||
}
|
||||
return s;
|
||||
|
||||
|
|
@ -95,9 +95,21 @@ Unix:
|
|||
return -1;
|
||||
sn = sizeof sun;
|
||||
if(bind(s, (struct sockaddr*)&sun, sizeof sun) < 0){
|
||||
if(errno == EADDRINUSE
|
||||
&& connect(s, (struct sockaddr*)&sun, sizeof sun) < 0
|
||||
&& errno == ECONNREFUSED){
|
||||
/* dead socket, so remove it */
|
||||
remove(unix);
|
||||
close(s);
|
||||
if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
||||
return -1;
|
||||
if(bind(s, (struct sockaddr*)&sun, sizeof sun) >= 0)
|
||||
goto Success;
|
||||
}
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
Success:
|
||||
listen(s, 8);
|
||||
putfd(dir, s);
|
||||
return s;
|
||||
|
|
@ -108,18 +120,15 @@ p9listen(char *dir, char *newdir)
|
|||
{
|
||||
int fd;
|
||||
|
||||
if((fd = getfd(dir)) < 0){
|
||||
if((fd = _p9netfd(dir)) < 0){
|
||||
werrstr("bad 'directory' in listen: %s", dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
print("accept %d", fd);
|
||||
if((fd = accept(fd, nil, nil)) < 0)
|
||||
return -1;
|
||||
print(" -> %d\n", fd);
|
||||
|
||||
putfd(newdir, fd);
|
||||
print("listen dir: %s\n", newdir);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +137,7 @@ p9accept(int cfd, char *dir)
|
|||
{
|
||||
int fd;
|
||||
|
||||
if((fd = getfd(dir)) < 0){
|
||||
if((fd = _p9netfd(dir)) < 0){
|
||||
werrstr("bad 'directory' in accept");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ static struct {
|
|||
#endif
|
||||
SIGUSR1, "sys: usr1",
|
||||
SIGUSR2, "sys: usr2",
|
||||
SIGPIPE, "sys: write on closed pipe",
|
||||
};
|
||||
|
||||
char*
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ convM2S(uchar *ap, uint nap, Fcall *f)
|
|||
break;
|
||||
|
||||
case Topen:
|
||||
case Topenfd:
|
||||
if(p+BIT32SZ+BIT8SZ > ep)
|
||||
return 0;
|
||||
f->fid = GBIT32(p);
|
||||
|
|
@ -260,6 +261,7 @@ convM2S(uchar *ap, uint nap, Fcall *f)
|
|||
break;
|
||||
|
||||
case Ropen:
|
||||
case Ropenfd:
|
||||
case Rcreate:
|
||||
p = gqid(p, ep, &f->qid);
|
||||
if(p == nil)
|
||||
|
|
@ -268,6 +270,12 @@ convM2S(uchar *ap, uint nap, Fcall *f)
|
|||
return 0;
|
||||
f->iounit = GBIT32(p);
|
||||
p += BIT32SZ;
|
||||
if(f->type == Ropenfd){
|
||||
if(p+BIT32SZ > ep)
|
||||
return 0;
|
||||
f->unixfd = GBIT32(p);
|
||||
p += BIT32SZ;
|
||||
}
|
||||
break;
|
||||
|
||||
case Rread:
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ sizeS2M(Fcall *f)
|
|||
break;
|
||||
|
||||
case Topen:
|
||||
case Topenfd:
|
||||
n += BIT32SZ;
|
||||
n += BIT8SZ;
|
||||
break;
|
||||
|
|
@ -164,6 +165,12 @@ sizeS2M(Fcall *f)
|
|||
n += BIT32SZ;
|
||||
break;
|
||||
|
||||
case Ropenfd:
|
||||
n += QIDSZ;
|
||||
n += BIT32SZ;
|
||||
n += BIT32SZ;
|
||||
break;
|
||||
|
||||
case Rread:
|
||||
n += BIT32SZ;
|
||||
n += f->count;
|
||||
|
|
@ -257,6 +264,7 @@ convS2M(Fcall *f, uchar *ap, uint nap)
|
|||
break;
|
||||
|
||||
case Topen:
|
||||
case Topenfd:
|
||||
PBIT32(p, f->fid);
|
||||
p += BIT32SZ;
|
||||
PBIT8(p, f->mode);
|
||||
|
|
@ -347,9 +355,14 @@ convS2M(Fcall *f, uchar *ap, uint nap)
|
|||
|
||||
case Ropen:
|
||||
case Rcreate:
|
||||
case Ropenfd:
|
||||
p = pqid(p, &f->qid);
|
||||
PBIT32(p, f->iounit);
|
||||
p += BIT32SZ;
|
||||
if(f->type == Ropenfd){
|
||||
PBIT32(p, f->unixfd);
|
||||
p += BIT32SZ;
|
||||
}
|
||||
break;
|
||||
|
||||
case Rread:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,54 @@
|
|||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
extern char *_p9translate(char*);
|
||||
|
||||
int
|
||||
create(char *path, int mode, ulong perm)
|
||||
p9create(char *xpath, int mode, ulong perm)
|
||||
{
|
||||
return open(path, mode|O_CREAT|O_TRUNC, perm);
|
||||
int fd, cexec, umode, rclose;
|
||||
char *path;
|
||||
|
||||
if((path = _p9translate(xpath)) == nil)
|
||||
return -1;
|
||||
|
||||
cexec = mode&OCEXEC;
|
||||
rclose = mode&ORCLOSE;
|
||||
mode &= ~(ORCLOSE|OCEXEC);
|
||||
|
||||
/* XXX should get mode mask right? */
|
||||
fd = -1;
|
||||
if(perm&DMDIR){
|
||||
if(mode != OREAD){
|
||||
werrstr("bad mode in directory create");
|
||||
goto out;
|
||||
}
|
||||
if(mkdir(path, perm&0777) < 0)
|
||||
goto out;
|
||||
fd = open(path, O_RDONLY);
|
||||
}else{
|
||||
umode = (mode&3)|O_CREAT|O_TRUNC;
|
||||
mode &= ~(3|OTRUNC);
|
||||
if(mode&OEXCL){
|
||||
umode |= O_EXCL;
|
||||
mode &= ~OEXCL;
|
||||
}
|
||||
if(mode){
|
||||
werrstr("unsupported mode in create");
|
||||
goto out;
|
||||
}
|
||||
fd = open(path, umode, perm);
|
||||
}
|
||||
out:
|
||||
if(fd >= 0){
|
||||
if(cexec)
|
||||
fcntl(fd, F_SETFL, FD_CLOEXEC);
|
||||
if(rclose)
|
||||
remove(path);
|
||||
}
|
||||
if(path != xpath)
|
||||
free(path);
|
||||
return fd;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,9 +74,16 @@ fcallfmt(Fmt *fmt)
|
|||
seprint(buf, e, "Topen tag %ud fid %ud mode %d", tag, fid, f->mode);
|
||||
break;
|
||||
case Ropen:
|
||||
seprint(buf, e, "Ropen tag %ud qid " QIDFMT " iounit %ud ", tag,
|
||||
seprint(buf, e, "Ropen tag %ud qid " QIDFMT " iounit %ud", tag,
|
||||
f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
|
||||
break;
|
||||
case Topenfd: /* 98 */
|
||||
seprint(buf, e, "Topenfd tag %ud fid %ud mode %d", tag, fid, f->mode);
|
||||
break;
|
||||
case Ropenfd:
|
||||
seprint(buf, e, "Ropenfd tag %ud qid " QIDFMT " iounit %ud unixfd %d", tag,
|
||||
f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit, f->unixfd);
|
||||
break;
|
||||
case Tcreate: /* 114 */
|
||||
seprint(buf, e, "Tcreate tag %ud fid %ud name %s perm %M mode %d", tag, fid, f->name, (ulong)f->perm, f->mode);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -13,3 +13,15 @@ p9getenv(char *s)
|
|||
return strdup(t);
|
||||
}
|
||||
|
||||
int
|
||||
p9putenv(char *s, char *v)
|
||||
{
|
||||
char *t;
|
||||
|
||||
t = smprint("%s=%s", s, v);
|
||||
if(t == nil)
|
||||
return -1;
|
||||
putenv(t);
|
||||
free(t);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ OFILES=\
|
|||
_p9dialparse.$O\
|
||||
_p9dir.$O\
|
||||
_p9proc.$O\
|
||||
_p9translate.$O\
|
||||
access.$O\
|
||||
announce.$O\
|
||||
argv0.$O\
|
||||
atexit.$O\
|
||||
|
|
@ -40,11 +42,13 @@ OFILES=\
|
|||
getcallerpc-$OBJTYPE.$O\
|
||||
getenv.$O\
|
||||
getfields.$O\
|
||||
getns.$O\
|
||||
getuser.$O\
|
||||
getwd.$O\
|
||||
jmp.$O\
|
||||
lock.$O\
|
||||
main.$O\
|
||||
malloc.$O\
|
||||
malloctag.$O\
|
||||
mallocz.$O\
|
||||
nan.$O\
|
||||
|
|
@ -53,13 +57,18 @@ OFILES=\
|
|||
notify.$O\
|
||||
nrand.$O\
|
||||
nulldir.$O\
|
||||
open.$O\
|
||||
pipe.$O\
|
||||
post9p.$O\
|
||||
postnote.$O\
|
||||
qlock.$O\
|
||||
quote.$O\
|
||||
read9pmsg.$O\
|
||||
readn.$O\
|
||||
rendez-$SYSNAME.$O\
|
||||
rfork.$O\
|
||||
seek.$O\
|
||||
sendfd.$O\
|
||||
sleep.$O\
|
||||
strecpy.$O\
|
||||
sysfatal.$O\
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ static int sigs[] = {
|
|||
#endif
|
||||
SIGFPE,
|
||||
SIGBUS,
|
||||
SIGSEGV,
|
||||
/* SIGSEGV, */
|
||||
SIGSYS,
|
||||
SIGPIPE,
|
||||
SIGALRM,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ p9rfork(int flags)
|
|||
if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){
|
||||
/* check other flags before we commit */
|
||||
flags &= ~(RFPROC|RFFDG);
|
||||
if(flags & ~(RFNOTEG)){
|
||||
if(flags & ~(RFNOTEG|RFNAMEG)){
|
||||
werrstr("unknown flags %08ux in rfork", flags);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -17,11 +17,14 @@ p9rfork(int flags)
|
|||
if(pid != 0)
|
||||
return pid;
|
||||
}
|
||||
|
||||
if(flags&RFPROC){
|
||||
werrstr("cannot use rfork to fork -- use ffork");
|
||||
werrstr("cannot use rfork for shared memory -- use ffork");
|
||||
return -1;
|
||||
}
|
||||
if(flags&RFNAMEG){
|
||||
/* XXX set $NAMESPACE to a new directory */
|
||||
flags &= ~RFNAMEG;
|
||||
}
|
||||
if(flags&RFNOTEG){
|
||||
setpgid(0, getpid());
|
||||
flags &= ~RFNOTEG;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue