shithub: mq

Download patch

ref: e4ac0181296586a41efb642e962281f03c099c2a
parent: 0768b64ca8608e7f6f374a139d0f921d06c6a24e
author: kvik <kvik@a-b.xyz>
date: Sat Jan 16 20:03:08 EST 2021

mq: fix Tcreate handling

When handling Tcreate we forgot that create(2) must also act as open(2),
that is, the server must initialize the state associated with the open
file in the same way it does when receiving an Topen call.

It also turned out that we needed to manually replace the fid->file
pointer with the new File, and also set the response qid to the new
file's qid.  This wasn't documented anywhere and it is likely that
the 9pfile(2) library can do it automatically, but until further
investigation we just do it ourselves.

--- a/src/mq.c
+++ b/src/mq.c
@@ -189,6 +189,23 @@
 }
 
 void
+streamopen(Stream *s, Req *r)
+{
+	Client *c;
+	
+	c = r->fid->aux = emalloc(sizeof(Client));
+	switch(s->mq->replay){
+	case Replayoff:
+		c->cursor = (Write*)s->queue->tail; break;
+	case Replaylast:
+		c->cursor = (Write*)s->queue->tail->tail; break;
+	case Replayall:
+		c->cursor = (Write*)s->queue; break;
+	}
+}
+
+
+void
 respondmessage(Req *r)
 {
 	int n;
@@ -443,8 +460,12 @@
 	case Qmq:
 		if(perm&DMDIR)
 			f = mqcreate(parent, name, uid, perm);
-		else
+		else{
 			f = streamcreate(parent, name, uid, perm);
+			r->fid->file = f;
+			r->ofcall.qid = f->qid;
+			streamopen(f->aux, r);
+		}
 		break;
 	}
 	if(f == nil)
@@ -460,21 +481,10 @@
 
 	switch(filetype(f)){
 	case Qstream:
-	case Qorder: {
-		Stream *s = f->aux;
-		Client *c;
-
-		c = r->fid->aux = emalloc(sizeof(Client));
-		switch(s->mq->replay){
-		case Replayoff:
-			c->cursor = (Write*)s->queue->tail; break;
-		case Replaylast:
-			c->cursor = (Write*)s->queue->tail->tail; break;
-		case Replayall:
-			c->cursor = (Write*)s->queue; break;
-		}
+	case Qorder:
+		streamopen(f->aux, r);
 		break;
-	}}
+	}
 	respond(r, nil);
 }