diff options
author | rsc <devnull@localhost> | 2003-12-11 17:48:38 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2003-12-11 17:48:38 +0000 |
commit | 32f69c36e0eec1227934bbd34854bfebd88686f2 (patch) | |
tree | 1587e9de84816b77168afa81c1594cc686809910 /src/lib9 | |
parent | ac244f8d287a6119155ea672c8fd13c487c5e4c7 (diff) | |
download | plan9port-32f69c36e0eec1227934bbd34854bfebd88686f2.tar.gz plan9port-32f69c36e0eec1227934bbd34854bfebd88686f2.tar.bz2 plan9port-32f69c36e0eec1227934bbd34854bfebd88686f2.zip |
Add support for user-level 9P servers/clients and various bug fixes to go with them.
Diffstat (limited to 'src/lib9')
-rw-r--r-- | src/lib9/announce.c | 25 | ||||
-rw-r--r-- | src/lib9/await.c | 1 | ||||
-rw-r--r-- | src/lib9/convM2S.c | 8 | ||||
-rw-r--r-- | src/lib9/convS2M.c | 13 | ||||
-rw-r--r-- | src/lib9/create.c | 50 | ||||
-rw-r--r-- | src/lib9/fcallfmt.c | 9 | ||||
-rw-r--r-- | src/lib9/getenv.c | 12 | ||||
-rw-r--r-- | src/lib9/mkfile | 9 | ||||
-rw-r--r-- | src/lib9/notify.c | 2 | ||||
-rw-r--r-- | src/lib9/rfork.c | 9 |
10 files changed, 123 insertions, 15 deletions
diff --git a/src/lib9/announce.c b/src/lib9/announce.c index 04c712d9..9f07bd22 100644 --- a/src/lib9/announce.c +++ b/src/lib9/announce.c @@ -5,13 +5,14 @@ #include <sys/socket.h> #include <netinet/in.h> #include <sys/un.h> +#include <errno.h> #undef sun #define sun sockun extern int _p9dialparse(char*, char**, char**, u32int*, int*); -static int -getfd(char *dir) +int +_p9netfd(char *dir) { int fd; @@ -83,7 +84,6 @@ p9announce(char *addr, char *dir) if(proto == SOCK_STREAM){ listen(s, 8); putfd(dir, s); -print("announce dir: %s\n", dir); } return s; @@ -95,9 +95,21 @@ Unix: return -1; sn = sizeof sun; if(bind(s, (struct sockaddr*)&sun, sizeof sun) < 0){ + if(errno == EADDRINUSE + && connect(s, (struct sockaddr*)&sun, sizeof sun) < 0 + && errno == ECONNREFUSED){ + /* dead socket, so remove it */ + remove(unix); + close(s); + if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + return -1; + if(bind(s, (struct sockaddr*)&sun, sizeof sun) >= 0) + goto Success; + } close(s); return -1; } +Success: listen(s, 8); putfd(dir, s); return s; @@ -108,18 +120,15 @@ p9listen(char *dir, char *newdir) { int fd; - if((fd = getfd(dir)) < 0){ + if((fd = _p9netfd(dir)) < 0){ werrstr("bad 'directory' in listen: %s", dir); return -1; } -print("accept %d", fd); if((fd = accept(fd, nil, nil)) < 0) return -1; -print(" -> %d\n", fd); putfd(newdir, fd); -print("listen dir: %s\n", newdir); return fd; } @@ -128,7 +137,7 @@ p9accept(int cfd, char *dir) { int fd; - if((fd = getfd(dir)) < 0){ + if((fd = _p9netfd(dir)) < 0){ werrstr("bad 'directory' in accept"); return -1; } diff --git a/src/lib9/await.c b/src/lib9/await.c index 89c695ae..5f2d58ba 100644 --- a/src/lib9/await.c +++ b/src/lib9/await.c @@ -45,6 +45,7 @@ static struct { #endif SIGUSR1, "sys: usr1", SIGUSR2, "sys: usr2", + SIGPIPE, "sys: write on closed pipe", }; char* diff --git a/src/lib9/convM2S.c b/src/lib9/convM2S.c index fcdcd42d..920775ea 100644 --- a/src/lib9/convM2S.c +++ b/src/lib9/convM2S.c @@ -138,6 +138,7 @@ convM2S(uchar *ap, uint nap, Fcall *f) break; case Topen: + case Topenfd: if(p+BIT32SZ+BIT8SZ > ep) return 0; f->fid = GBIT32(p); @@ -260,6 +261,7 @@ convM2S(uchar *ap, uint nap, Fcall *f) break; case Ropen: + case Ropenfd: case Rcreate: p = gqid(p, ep, &f->qid); if(p == nil) @@ -268,6 +270,12 @@ convM2S(uchar *ap, uint nap, Fcall *f) return 0; f->iounit = GBIT32(p); p += BIT32SZ; + if(f->type == Ropenfd){ + if(p+BIT32SZ > ep) + return 0; + f->unixfd = GBIT32(p); + p += BIT32SZ; + } break; case Rread: diff --git a/src/lib9/convS2M.c b/src/lib9/convS2M.c index 9acdcfa5..6e9d2719 100644 --- a/src/lib9/convS2M.c +++ b/src/lib9/convS2M.c @@ -92,6 +92,7 @@ sizeS2M(Fcall *f) break; case Topen: + case Topenfd: n += BIT32SZ; n += BIT8SZ; break; @@ -164,6 +165,12 @@ sizeS2M(Fcall *f) n += BIT32SZ; break; + case Ropenfd: + n += QIDSZ; + n += BIT32SZ; + n += BIT32SZ; + break; + case Rread: n += BIT32SZ; n += f->count; @@ -257,6 +264,7 @@ convS2M(Fcall *f, uchar *ap, uint nap) break; case Topen: + case Topenfd: PBIT32(p, f->fid); p += BIT32SZ; PBIT8(p, f->mode); @@ -347,9 +355,14 @@ convS2M(Fcall *f, uchar *ap, uint nap) case Ropen: case Rcreate: + case Ropenfd: p = pqid(p, &f->qid); PBIT32(p, f->iounit); p += BIT32SZ; + if(f->type == Ropenfd){ + PBIT32(p, f->unixfd); + p += BIT32SZ; + } break; case Rread: diff --git a/src/lib9/create.c b/src/lib9/create.c index abef0c35..bdad5f6a 100644 --- a/src/lib9/create.c +++ b/src/lib9/create.c @@ -1,8 +1,54 @@ #include <u.h> +#define NOPLAN9DEFINES #include <libc.h> +#include <sys/stat.h> + +extern char *_p9translate(char*); int -create(char *path, int mode, ulong perm) +p9create(char *xpath, int mode, ulong perm) { - return open(path, mode|O_CREAT|O_TRUNC, perm); + int fd, cexec, umode, rclose; + char *path; + + if((path = _p9translate(xpath)) == nil) + return -1; + + cexec = mode&OCEXEC; + rclose = mode&ORCLOSE; + mode &= ~(ORCLOSE|OCEXEC); + + /* XXX should get mode mask right? */ + fd = -1; + if(perm&DMDIR){ + if(mode != OREAD){ + werrstr("bad mode in directory create"); + goto out; + } + if(mkdir(path, perm&0777) < 0) + goto out; + fd = open(path, O_RDONLY); + }else{ + umode = (mode&3)|O_CREAT|O_TRUNC; + mode &= ~(3|OTRUNC); + if(mode&OEXCL){ + umode |= O_EXCL; + mode &= ~OEXCL; + } + if(mode){ + werrstr("unsupported mode in create"); + goto out; + } + fd = open(path, umode, perm); + } +out: + if(fd >= 0){ + if(cexec) + fcntl(fd, F_SETFL, FD_CLOEXEC); + if(rclose) + remove(path); + } + if(path != xpath) + free(path); + return fd; } diff --git a/src/lib9/fcallfmt.c b/src/lib9/fcallfmt.c index 4eef88de..592316fe 100644 --- a/src/lib9/fcallfmt.c +++ b/src/lib9/fcallfmt.c @@ -74,9 +74,16 @@ fcallfmt(Fmt *fmt) seprint(buf, e, "Topen tag %ud fid %ud mode %d", tag, fid, f->mode); break; case Ropen: - seprint(buf, e, "Ropen tag %ud qid " QIDFMT " iounit %ud ", tag, + seprint(buf, e, "Ropen tag %ud qid " QIDFMT " iounit %ud", tag, f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit); break; + case Topenfd: /* 98 */ + seprint(buf, e, "Topenfd tag %ud fid %ud mode %d", tag, fid, f->mode); + break; + case Ropenfd: + seprint(buf, e, "Ropenfd tag %ud qid " QIDFMT " iounit %ud unixfd %d", tag, + f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit, f->unixfd); + break; case Tcreate: /* 114 */ seprint(buf, e, "Tcreate tag %ud fid %ud name %s perm %M mode %d", tag, fid, f->name, (ulong)f->perm, f->mode); break; diff --git a/src/lib9/getenv.c b/src/lib9/getenv.c index c6ff7160..2a2d1391 100644 --- a/src/lib9/getenv.c +++ b/src/lib9/getenv.c @@ -13,3 +13,15 @@ p9getenv(char *s) return strdup(t); } +int +p9putenv(char *s, char *v) +{ + char *t; + + t = smprint("%s=%s", s, v); + if(t == nil) + return -1; + putenv(t); + free(t); + return 0; +} diff --git a/src/lib9/mkfile b/src/lib9/mkfile index 14d8c0e0..a0e75fc3 100644 --- a/src/lib9/mkfile +++ b/src/lib9/mkfile @@ -8,6 +8,8 @@ OFILES=\ _p9dialparse.$O\ _p9dir.$O\ _p9proc.$O\ + _p9translate.$O\ + access.$O\ announce.$O\ argv0.$O\ atexit.$O\ @@ -40,11 +42,13 @@ OFILES=\ getcallerpc-$OBJTYPE.$O\ getenv.$O\ getfields.$O\ + getns.$O\ getuser.$O\ getwd.$O\ jmp.$O\ lock.$O\ main.$O\ + malloc.$O\ malloctag.$O\ mallocz.$O\ nan.$O\ @@ -53,13 +57,18 @@ OFILES=\ notify.$O\ nrand.$O\ nulldir.$O\ + open.$O\ + pipe.$O\ + post9p.$O\ postnote.$O\ qlock.$O\ quote.$O\ + read9pmsg.$O\ readn.$O\ rendez-$SYSNAME.$O\ rfork.$O\ seek.$O\ + sendfd.$O\ sleep.$O\ strecpy.$O\ sysfatal.$O\ diff --git a/src/lib9/notify.c b/src/lib9/notify.c index 460eabfe..160755d0 100644 --- a/src/lib9/notify.c +++ b/src/lib9/notify.c @@ -19,7 +19,7 @@ static int sigs[] = { #endif SIGFPE, SIGBUS, - SIGSEGV, +/* SIGSEGV, */ SIGSYS, SIGPIPE, SIGALRM, diff --git a/src/lib9/rfork.c b/src/lib9/rfork.c index 270c3cdd..f3a21928 100644 --- a/src/lib9/rfork.c +++ b/src/lib9/rfork.c @@ -9,7 +9,7 @@ p9rfork(int flags) if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){ /* check other flags before we commit */ flags &= ~(RFPROC|RFFDG); - if(flags & ~(RFNOTEG)){ + if(flags & ~(RFNOTEG|RFNAMEG)){ werrstr("unknown flags %08ux in rfork", flags); return -1; } @@ -17,11 +17,14 @@ p9rfork(int flags) if(pid != 0) return pid; } - if(flags&RFPROC){ - werrstr("cannot use rfork to fork -- use ffork"); + werrstr("cannot use rfork for shared memory -- use ffork"); return -1; } + if(flags&RFNAMEG){ + /* XXX set $NAMESPACE to a new directory */ + flags &= ~RFNAMEG; + } if(flags&RFNOTEG){ setpgid(0, getpid()); flags &= ~RFNOTEG; |