aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2006-05-05 04:55:14 +0000
committerrsc <devnull@localhost>2006-05-05 04:55:14 +0000
commit663017560218b62119022f9f4360cf6eb05a36e2 (patch)
treee38c0d7cda94f06bde1327af7f804d04b506906a
parent11b0772a33026b44fd0a7f8a8d757d2f6a218878 (diff)
downloadplan9port-663017560218b62119022f9f4360cf6eb05a36e2.tar.gz
plan9port-663017560218b62119022f9f4360cf6eb05a36e2.tar.bz2
plan9port-663017560218b62119022f9f4360cf6eb05a36e2.zip
fix edit pipe bug
-rw-r--r--src/cmd/acme/dat.h3
-rw-r--r--src/cmd/acme/ecmd.c18
-rw-r--r--src/cmd/acme/xfid.c29
3 files changed, 48 insertions, 2 deletions
diff --git a/src/cmd/acme/dat.h b/src/cmd/acme/dat.h
index 0bf82381..075ffe22 100644
--- a/src/cmd/acme/dat.h
+++ b/src/cmd/acme/dat.h
@@ -269,6 +269,7 @@ struct Window
int tagexpand;
int taglines;
Rectangle tagtop;
+ QLock editoutlk;
};
void wininit(Window*, Window*, Rectangle);
@@ -562,4 +563,6 @@ Channel *cerr; /* chan(char*) */
Channel *cedit; /* chan(int) */
Channel *cwarn; /* chan(void*)[1] (really chan(unit)[1]) */
+QLock editoutlk;
+
#define STACK 32768
diff --git a/src/cmd/acme/ecmd.c b/src/cmd/acme/ecmd.c
index ac578235..a507b50f 100644
--- a/src/cmd/acme/ecmd.c
+++ b/src/cmd/acme/ecmd.c
@@ -592,6 +592,7 @@ runpipe(Text *t, int cmd, Rune *cr, int ncr, int state)
int n;
Runestr dir;
Window *w;
+ QLock *q;
r = skipbl(cr, ncr, &n);
if(n == 0)
@@ -626,6 +627,23 @@ runpipe(Text *t, int cmd, Rune *cr, int ncr, int state)
winunlock(t->w);
qunlock(&row.lk);
recvul(cedit);
+ /*
+ * The editoutlk exists only so that we can tell when
+ * the editout file has been closed. It can get closed *after*
+ * the process exits because, since the process cannot be
+ * connected directly to editout (no 9P kernel support),
+ * the process is actually connected to a pipe to another
+ * process (arranged via 9pserve) that reads from the pipe
+ * and then writes the data in the pipe to editout using
+ * 9P transactions. This process might still have a couple
+ * writes left to copy after the original process has exited.
+ */
+ if(w)
+ q = &w->editoutlk;
+ else
+ q = &editoutlk;
+ qlock(q); /* wait for file to close */
+ qunlock(q);
qlock(&row.lk);
editing = Inactive;
if(t!=nil && t->w!=nil)
diff --git a/src/cmd/acme/xfid.c b/src/cmd/acme/xfid.c
index 15b411ce..65ae2d99 100644
--- a/src/cmd/acme/xfid.c
+++ b/src/cmd/acme/xfid.c
@@ -98,9 +98,9 @@ xfidopen(Xfid *x)
w = x->f->w;
t = &w->body;
+ q = FILE(x->f->qid);
if(w){
winlock(w, 'E');
- q = FILE(x->f->qid);
switch(q){
case QWaddr:
if(w->nopen[q]++ == 0){
@@ -174,11 +174,26 @@ xfidopen(Xfid *x)
respond(x, &fc, Eperm);
return;
}
+ if(!canqlock(&w->editoutlk)){
+ winunlock(w);
+ respond(x, &fc, Einuse);
+ return;
+ }
w->wrselrange = range(t->q1, t->q1);
break;
}
winunlock(w);
}
+ else{
+ switch(q){
+ case Qeditout:
+ if(!canqlock(&editoutlk)){
+ respond(x, &fc, Einuse);
+ return;
+ }
+ break;
+ }
+ }
fc.qid = x->f->qid;
fc.iounit = messagesize-IOHDRSZ;
x->f->open = TRUE;
@@ -203,10 +218,10 @@ xfidclose(Xfid *x)
return;
}
+ q = FILE(x->f->qid);
x->f->open = FALSE;
if(w){
winlock(w, 'E');
- q = FILE(x->f->qid);
switch(q){
case QWctl:
if(w->ctlfid!=~0 && w->ctlfid==x->f->fid){
@@ -247,10 +262,20 @@ xfidclose(Xfid *x)
min(w->wrselrange.q1, t->file->b.nc), 1);
textscrdraw(t);
break;
+ case QWeditout:
+ qunlock(&w->editoutlk);
+ break;
}
winunlock(w);
winclose(w);
}
+ else{
+ switch(q){
+ case Qeditout:
+ qunlock(&editoutlk);
+ break;
+ }
+ }
respond(x, &fc, nil);
}