aboutsummaryrefslogtreecommitdiff
path: root/src/lib9
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-12-11 17:48:38 +0000
committerrsc <devnull@localhost>2003-12-11 17:48:38 +0000
commit32f69c36e0eec1227934bbd34854bfebd88686f2 (patch)
tree1587e9de84816b77168afa81c1594cc686809910 /src/lib9
parentac244f8d287a6119155ea672c8fd13c487c5e4c7 (diff)
downloadplan9port-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.c25
-rw-r--r--src/lib9/await.c1
-rw-r--r--src/lib9/convM2S.c8
-rw-r--r--src/lib9/convS2M.c13
-rw-r--r--src/lib9/create.c50
-rw-r--r--src/lib9/fcallfmt.c9
-rw-r--r--src/lib9/getenv.c12
-rw-r--r--src/lib9/mkfile9
-rw-r--r--src/lib9/notify.c2
-rw-r--r--src/lib9/rfork.c9
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;