M gnot/dat.h => gnot/dat.h +1 -1
@@ 327,7 327,7 @@ struct Proc
ulong pc; /* DEBUG only */
};
-#define NERR 10
+#define NERR 15
#define NNOTE 5
#define NFD 100
struct User
M gnot/devpipe.c => gnot/devpipe.c +8 -7
@@ 70,8 70,10 @@ pipeclone(Chan *c, Chan *nc)
* up the inuse count of each stream to reflect the
* pointer from the other stream.
*/
- streamenter(c->stream);
- streamenter(nc->stream);
+ if(streamenter(c->stream)<0)
+ panic("pipeattach");
+ if(streamenter(nc->stream)<0)
+ panic("pipeattach");
return nc;
}
@@ 131,6 133,7 @@ pipeclose(Chan *c)
}
streamclose(c); /* close this stream */
streamexit(other, 0); /* release stream for other half of pipe */
+ poperror();
}
long
@@ 206,9 209,7 @@ pipestclose(Queue *q)
* send a hangup
*/
q = q->other;
- if(q->next){
- bp = allocb(0);
- bp->type = M_HANGUP;
- pipeiput(q->next, bp);
- }
+ bp = allocb(0);
+ bp->type = M_HANGUP;
+ PUTNEXT(q, bp);
}
M gnot/stream.c => gnot/stream.c +36 -38
@@ 531,8 531,12 @@ prepend(Block *bp, int n)
void
nullput(Queue *q, Block *bp)
{
- freeb(bp);
- error(0, Ehungup);
+ if(bp->type == M_HANGUP)
+ freeb(bp);
+ else {
+ freeb(bp);
+ error(0, Ehungup);
+ }
}
/*
@@ 757,21 761,17 @@ streamexit(Stream *s, int locked)
if(!locked)
lock(s);
- s->inuse--;
- if(s->inuse != 0){
- if(!locked)
- unlock(s);
- return;
- }
-
- /*
- * ascend the stream freeing the queues
- */
- for(q = s->devq; q; q = nq){
- nq = q->next;
- freeq(q);
+ if(s->inuse == 1){
+ /*
+ * ascend the stream freeing the queues
+ */
+ for(q = s->devq; q; q = nq){
+ nq = q->next;
+ freeq(q);
+ }
+ s->id = s->dev = s->type = 0;
}
- s->id = s->dev = s->type = 0;
+ s->inuse--;
if(!locked)
unlock(s);
}
@@ 797,29 797,27 @@ streamclose(Chan *c)
* decrement the reference count
*/
lock(s);
- if(s->opens != 1){
- s->opens--;
- unlock(c->stream);
- return;
- }
-
- /*
- * descend the stream closing the queues
- */
- for(q = s->procq; q; q = q->next){
- if(q->info->close)
- (*q->info->close)(q->other);
- if(q == s->devq->other)
- break;
- }
-
- /*
- * ascend the stream flushing the queues
- */
- for(q = s->devq; q; q = nq){
- nq = q->next;
- flushq(q);
+ if(s->opens == 1){
+ /*
+ * descend the stream closing the queues
+ */
+ for(q = s->procq; q; q = q->next){
+ if(q->info->close)
+ (*q->info->close)(q->other);
+ /* this may be 2 streams joined device end to device end */
+ if(q == s->devq->other)
+ break;
+ }
+
+ /*
+ * ascend the stream flushing the queues
+ */
+ for(q = s->devq; q; q = nq){
+ nq = q->next;
+ flushq(q);
+ }
}
+ s->opens--;
/*
* leave it and free it