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

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

View file

@ -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;
}

View file

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

View file

@ -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:

View file

@ -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:

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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\

View file

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

View file

@ -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;