Commit Diff


commit - 7f11104a5737adf261d10bc1a7b85e740f2eb491
commit + 49588d5d9089589ccda28c41aae90c29d6f72787
blob - c33beb142926698c48fc59922888ed08c1937136
blob + eb2df758a614caeebd54ccba8f27ccf0e978241a
--- src/cmd/9pserve.c
+++ src/cmd/9pserve.c
@@ -352,8 +352,8 @@ connthread(void *arg)
 			m->afid->ref++;
 			break;
 		case Topenfd:
-			if(m->tx.mode != OREAD && (m->tx.mode&~OTRUNC) != OWRITE){
-				err(m, "openfd mode must be OREAD or OWRITE");
+			if(m->tx.mode&~(OTRUNC|3)){
+				err(m, "bad openfd mode");
 				continue;
 			}
 			m->isopenfd = 1;
@@ -489,13 +489,17 @@ openfdthread(void *v)
 			m->ref++;
 			sendomsg(m);
 			recvp(c->internal);
-			if(m->rx.type == Rerror)
+			if(m->rx.type == Rerror){
+			//	fprint(2, "read error: %s\n", m->rx.ename);
 				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)
+			if(iowrite(io, c->fd, m->rx.data, m->rx.count) != m->rx.count){
+				fprint(2, "pipe write error: %r\n");
 				break;
+			}
 			msgput(m);
 			msgput(m);
 		}
@@ -503,6 +507,8 @@ openfdthread(void *v)
 		for(;;){
 			if(verbose) fprint(2, "twrite...");
 			if((n=ioread(io, c->fd, buf, sizeof buf)) <= 0){
+				if(n < 0)
+					fprint(2, "pipe read error: %r\n");
 				m = nil;
 				break;
 			}
@@ -520,8 +526,10 @@ openfdthread(void *v)
 			m->ref++;
 			sendomsg(m);
 			recvp(c->internal);
-			if(m->rx.type == Rerror)
-				break;
+			if(m->rx.type == Rerror){
+			//	fprint(2, "write error: %s\n", m->rx.ename);
+				continue;
+			}
 			tot = n;
 			msgput(m);
 			msgput(m);
@@ -534,18 +542,20 @@ openfdthread(void *v)
 		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);
+	if(fid->ref == 1){
+		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);
@@ -578,13 +588,24 @@ xopenfd(Msg *m)
 	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);
 
+	/* if mode is ORDWR, that openfdthread will write; start a reader */
+	if((m->tx.mode&3) == ORDWR){
+		nc = emalloc(sizeof(Conn));
+		nc->internal = chancreate(sizeof(void*), 0);
+		nc->fdfid = m->fid;
+		m->fid->ref++;
+		nc->fdmode = OREAD;
+		nc->fd = dup(p[0], -1);
+		threadcreate(openfdthread, nc, STACK);
+	}
+
+	/* steal fid from other connection */
+	if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0)
+		fidput(m->fid);
+
 	/* rewrite as Ropenfd */
 	m->rx.type = Ropenfd;
 	n = GBIT32(m->rpkt);
@@ -1265,7 +1286,7 @@ iowrite(Ioproc *io, int fd, void *v, long n)
 	u = v;
 	for(tot=0; tot<n; tot+=m){
 		m = _iowrite(io, fd, u+tot, n-tot);
-		if(m <= 0){
+		if(m < 0){
 			if(tot)
 				break;
 			return m;
blob - cd333dc7ac7d181ad1f981204456741d0e2f1703
blob + d220bdef60b654d4e6d2e10e7a0bd2e79cd0632c
--- src/cmd/acme/fsys.c
+++ src/cmd/acme/fsys.c
@@ -306,6 +306,7 @@ fsysattach(Xfid *x, Fid *f)
 	Fcall t;
 	int id;
 	Mntdir *m;
+	char buf[128];
 
 	if(strcmp(x->fcall.uname, user) != 0)
 		return respond(x, &t, Eperm);
@@ -327,8 +328,10 @@ fsysattach(Xfid *x, Fid *f)
 			m->ref++;
 			break;
 		}
-	if(m == nil)
-		sendp(cerr, estrdup("unknown id in attach"));
+	if(m == nil){
+		snprint(buf, sizeof buf, "unknown id '%s' in attach", x->fcall.aname);
+		sendp(cerr, estrdup(buf));
+	}
 	qunlock(&mnt.lk);
 	return respond(x, &t, nil);
 }
blob - 84149eb97a6e620216a58418a652e3980618db8c
blob + f92f903afbab6d183d02fbd1ad740653cc4c6298
--- src/cmd/acme/mkfile
+++ src/cmd/acme/mkfile
@@ -36,6 +36,6 @@ UPDATE=\
 
 <$PLAN9/src/mkone
 
-LDFLAGS=$LDFLAGS -lfs -lmux -lplumb -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11
+LDFLAGS=$LDFLAGS -lplumb -lfs -lmux -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11
 
 edit.$O ecmd.$O elog.$O:	edit.h
blob - f397623ed4bdb89e0f9f53aad5bfcaf41a9eb222
blob + 13af7395986850060a84fd00ea113bd4877bf4be
--- src/cmd/acme/xfid.c
+++ src/cmd/acme/xfid.c
@@ -194,6 +194,7 @@ xfidclose(Xfid *x)
 
 	w = x->f->w;
 	x->f->busy = FALSE;
+	x->f->w = nil;
 	if(x->f->open == FALSE){
 		if(w != nil)
 			winclose(w);
blob - e2131e777df8a1e39e9d48c05ffa8ac90bc5b489
blob + f6365ac00ce6776125795f7c337a0a12edb75719
--- src/cmd/mkfile
+++ src/cmd/mkfile
@@ -6,7 +6,7 @@ LDFLAGS=$LDFLAGS -lthread -lsec -lfs -lmux -lregexp9 -
 
 <$PLAN9/src/mkmany
 
-BUGGERED='CVS|oplumb|plumb2|mk|vac|9term|venti|htmlfmt'
+BUGGERED='CVS|faces|factotum|oplumb|plumb2|mk|vac|9term|upas|venti|htmlfmt'
 DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "$BUGGERED"`
 
 <$PLAN9/src/mkdirs
blob - 160755d0b91ba317d7f5585acc8f94be22da492a
blob + 2e589de750352136856816e158011977e6a92b2d
--- src/lib9/notify.c
+++ src/lib9/notify.c
@@ -7,33 +7,37 @@
 
 extern char *_p9sigstr(int, char*);
 
-static int sigs[] = {
-	SIGHUP,
-	SIGINT,
-	SIGQUIT,
-	SIGILL,
-	SIGTRAP,
+static struct {
+	int sig;
+	int restart;
+} sigs[] = {
+	SIGHUP, 0,
+	SIGINT, 0,
+	SIGQUIT, 0,
+	SIGILL, 0,
+	SIGTRAP, 0,
 /*	SIGABRT,	*/
 #ifdef SIGEMT
-	SIGEMT,
+	SIGEMT, 0,
 #endif
-	SIGFPE,
-	SIGBUS,
+	SIGFPE, 0,
+	SIGBUS, 0,
 /*	SIGSEGV,	*/
-	SIGSYS,
-	SIGPIPE,
-	SIGALRM,
-	SIGTERM,
-	SIGTSTP,
-	SIGTTIN,
-	SIGTTOU,
-	SIGXCPU,
-	SIGXFSZ,
-	SIGVTALRM,
-	SIGUSR1,
-	SIGUSR2,
+	SIGCHLD, 1,
+	SIGSYS, 0,
+	SIGPIPE, 0,
+	SIGALRM, 0,
+	SIGTERM, 0,
+	SIGTSTP, 1,
+	SIGTTIN, 1,
+	SIGTTOU, 1,
+	SIGXCPU, 0,
+	SIGXFSZ, 0,
+	SIGVTALRM, 0,
+	SIGUSR1, 0,
+	SIGUSR2, 0,
 #ifdef SIGINFO
-	SIGINFO,
+	SIGINFO, 0,
 #endif
 };
 
@@ -72,8 +76,13 @@ notify(void (*f)(void*, char*))
 		notifyf = f;
 		sa.sa_handler = notifysigf;
 	}
-	for(i=0; i<nelem(sigs); i++)
-		sigaction(sigs[i], &sa, 0);
+	for(i=0; i<nelem(sigs); i++){
+		if(sigs[i].restart)
+			sa.sa_flags |= SA_RESTART;
+		else
+			sa.sa_flags &= ~SA_RESTART;
+		sigaction(sigs[i].sig, &sa, 0);
+	}
 	return 0;
 }
 
blob - 77a03a0fba4efabbec6efe3b7cc1b59819e8b43a
blob + 28c9d1cfd9bef4c0d5f4d3b779f4a15f8cbf8654
--- src/libfs/ns.c
+++ src/libfs/ns.c
@@ -25,6 +25,7 @@ nsmount(char *name, char *aname)
 		werrstr("dial %s: %r", addr);
 		return nil;
 	}
+	fcntl(fd, F_SETFL, FD_CLOEXEC);
 
 	fs = fsmount(fd, aname);
 	if(fs == nil){
blob - fcade7f4c9a0885db50e98668d0582b14e1d6642
blob + fd95810b3e06ebdb605a9201b7fd67bae91e966d
--- src/libplumb/mesg.c
+++ src/libplumb/mesg.c
@@ -7,19 +7,66 @@
 static char attrbuf[4096];
 
 char *home;
-
+static Fsys *fsplumb;
+static int pfd = -1;
+static Fid *pfid;
 int
 plumbopen(char *name, int omode)
 {
-	Fsys *fs;
 	int fd;
 
-	fs = nsmount("plumb", "");
-	if(fs == nil)
+	if(fsplumb == nil)
+		fsplumb = nsmount("plumb", "");
+	if(fsplumb == nil)
 		return -1;
-	fd = fsopenfd(fs, name, omode);
-	fsunmount(fs);
+	/*
+	 * It's important that when we send something,
+	 * we find out whether it was a valid plumb write.
+	 * (If it isn't, the client might fall back to some
+	 * other mechanism or indicate to the user what happened.)
+	 * We can't use a pipe for this, so we have to use the
+	 * fid interface.  But we need to return a fd. 
+	 * Return a fd for /dev/null so that we return a unique
+	 * file descriptor.  In plumbsend we'll look for pfd
+	 * and use the recorded fid instead.
+	 */
+	if((omode&3) == OWRITE){
+		if(pfd != -1){
+			werrstr("already have plumb send open");
+			return -1;
+		}
+		pfd = open("/dev/null", OWRITE);
+		if(pfd < 0)
+			return -1;
+		pfid = fsopen(fsplumb, name, omode);
+		if(pfid == nil){
+			close(pfd);
+			pfd = -1;
+			return -1;
+		}
+		return pfd;
+	}
+
+	fd = fsopenfd(fsplumb, name, omode);
 	return fd;
+}
+
+int
+plumbsend(int fd, Plumbmsg *m)
+{
+	char *buf;
+	int n;
+
+	if(fd != pfd){
+		werrstr("fd is not the plumber");
+		return -1;
+	}
+	buf = plumbpack(m, &n);
+	if(buf == nil)
+		return -1;
+	n = fswrite(pfid, buf, n);
+	free(buf);
+	return n;
 }
 
 static int
@@ -144,20 +191,6 @@ plumbpack(Plumbmsg *m, int *np)
 	return buf;
 }
 
-int
-plumbsend(int fd, Plumbmsg *m)
-{
-	char *buf;
-	int n;
-
-	buf = plumbpack(m, &n);
-	if(buf == nil)
-		return -1;
-	n = write(fd, buf, n);
-	free(buf);
-	return n;
-}
-
 static int
 plumbline(char **linep, char *buf, int i, int n, int *bad)
 {
blob - 074556f9b50819c8d8525aefdd419a2851cdbb92
blob + 35e2ab6f87f746e3acc9434f2e5571c0184b4145
--- src/libthread/asm-FreeBSD-386.s
+++ src/libthread/asm-FreeBSD-386.s
@@ -30,20 +30,20 @@ _gotolabel:
 	ret
 
 
-.globl	_xinc
-_xinc:
-	movl 4(%esp), %eax
-	lock incl 0(%eax)
-	ret
-
-.globl	_xdec
-_xdec:
-	movl 4(%esp), %eax
-	lock decl 0(%eax)
-	jz iszero
-	movl $1, %eax
-	ret
-iszero:
-	movl $0, %eax
-	ret
-
+# .globl	_xinc
+# _xinc:
+# 	movl 4(%esp), %eax
+# 	lock incl 0(%eax)
+# 	ret
+# 
+# .globl	_xdec
+# _xdec:
+# 	movl 4(%esp), %eax
+# 	lock decl 0(%eax)
+# 	jz iszero
+# 	movl $1, %eax
+# 	ret
+# iszero:
+# 	movl $0, %eax
+# 	ret
+# 
blob - 97c756079abe0771ca6d34141a4f2078e49d5a71
blob + c04d414cf5d00de94725e48a0fcc9c32e030cdc0
--- src/libthread/exec-unix.c
+++ src/libthread/exec-unix.c
@@ -122,6 +122,7 @@ efork(void *ve)
 	for(i=3; i<40; i++)
 		if(i != e->fd[1])
 			close(i);
+	rfork(RFNOTEG);
 	execvp(e->prog, e->args);
 	_threaddebug(DBGEXEC, "_schedexec failed: %r");
 	rerrstr(buf, sizeof buf);
blob - 9b78e63e6f4b8ffad00f2af24936e1d932f4ee5f
blob + 8f50fd5fea8845646d70b613443e3fcef89cf404
--- src/libthread/ref.c
+++ src/libthread/ref.c
@@ -3,11 +3,18 @@
 void
 incref(Ref *r)
 {
-	_xinc(&r->ref);
+	lock(&r->lk);
+	r->ref++;
+	unlock(&r->lk);
 }
 
 long
 decref(Ref *r)
 {
-	return _xdec(&r->ref);
+	long n;
+
+	lock(&r->lk);
+	n = --r->ref;
+	unlock(&r->lk);
+	return n;
 }