shithub: mq

Download patch

ref: 081ed9fecdb571030ee202e8014e8de58acca206
parent: 90a6fc91052ebe27f3e1fa0d96d0876c00b48ff3
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Sep 17 14:03:49 EDT 2023

mq: fix some bugs and crashes

--- a/mq.c
+++ b/mq.c
@@ -11,8 +11,14 @@
 
 enum {
 	Qroot,
+	Maxqid,
 };
 
+enum {
+	Cclose,
+	Ctrunc,
+};
+
 struct Aux {
 	Mq	*q;
 	int	id;
@@ -35,8 +41,9 @@
 };
 
 struct Mq {
+	Ref;
 	Qid	qid;
-	int	count;
+	int	moribund;
 	usize	logsz;
 	Msg	*loghd;
 	Msg	*logtl;
@@ -55,12 +62,16 @@
 Mq	**queues;
 int	nqueues;
 vlong	maxlog = -1;
-vlong	queueid = Qroot + 1;
+vlong	queueid = Maxqid;
 
 char Ebaduse[] = "invalid use of fd";
 char Einuse[] = "fid in use";
 char Eexist[] = "file already exists";
-char Enoexist[] = "file does not exists";
+char Enoexist[] = "file does not exist";
+char Eintr[] = "interrupted";
+char Enotdir[] = "not a directory";
+char Ebadcmd[] = "unknown command";
+char Enomem[] = "out of memory";
 
 void *
 emalloc(ulong n)
@@ -96,21 +107,7 @@
 	return s;
 }
 
-Msg*
-msgref(Msg *m)
-{
-	incref(m);
-	return m;
-}
-
 void
-msgunref(Msg *m)
-{
-	if(decref(m) == 0)
-		free(m);
-}
-
-void
 trimlog(Mq *q)
 {
 	Msg *m;
@@ -121,7 +118,8 @@
 		m = q->loghd;
 		q->loghd = m->next;
 		q->logsz -= m->count;
-		msgunref(m);
+		if(decref(m) == 0)
+			free(m);
 	}
 	if(q->loghd == nil)
 		q->logtl = nil;
@@ -151,7 +149,7 @@
 	rd->hd = q->loghd;
 	rd->tl = q->logtl;
 	for(m = q->loghd; m != nil; m = m->next)
-		msgref(m);
+		incref(m);
 	return rd->id;
 }
 
@@ -214,12 +212,12 @@
 		if(strcmp(name, "..") == 0){
 			*qid = f->qid;
 			return nil;
+		}else if((q = lookup(name)) != nil){
+			f->qid = q->qid;
+			*qid = f->qid;
+			return nil;
 		}
-		if((q = lookup(name)) == nil)
-			return Enoexist;
-		f->qid = q->qid;
-		*qid = f->qid;
-		return nil;
+		return Enoexist;
 	default:
 		if(strcmp(name, "..") == 0){
 			f->qid = (Qid){Qroot, 0, QTDIR};
@@ -226,7 +224,7 @@
 			*qid = f->qid;
 			return nil;
 		}
-		return "not a dir";
+		return Enotdir;
 	}	
 }
 
@@ -267,8 +265,24 @@
 void
 mqremove(Req *r)
 {
-	USED(r);
-	abort();
+	vlong path;
+	int i, o;
+
+	path = r->fid->qid.path;
+	if(path == Qroot){
+		respond(r, Ebaduse);
+		return;
+	}
+	o = 0;
+	for(i = 0; i < nqueues; i++){
+		if(queues[i]->qid.path == path){
+			queues[i]->moribund = 1;
+			continue;
+		}
+		queues[o++] = queues[i];
+	}
+	nqueues--;
+	respond(r, nil);
 }
 
 void
@@ -311,13 +325,14 @@
 		if(q->rd[i].tl != nil)
 			q->rd[i].tl->next = m;
 		q->rd[i].tl = m;
-		msgref(m);
+		incref(m);
 	}
 	if(q->loghd == nil)
 		q->loghd = m;
 	if(q->logtl != nil)
 		q->logtl->next = m;
-	q->logtl = msgref(m);
+	incref(m);
+	q->logtl = m;
 	q->logsz += m->count;
 	q->logtl = m;
 
@@ -369,7 +384,8 @@
 		rd->hd = m->next;
 		if(rd->hd == nil)
 			rd->tl = nil;
-		msgunref(m);
+		if(decref(m) == 0)
+			free(m);
 	}
 }
 
@@ -419,7 +435,8 @@
 	p = r->fid->qid.path;
 	a = emalloc(sizeof(Aux));
 	if(p != Qroot){
-		a->q = queues[p-1];
+		incref(queues[p-Maxqid]);
+		a->q = queues[p-Maxqid];
 		if(m == OREAD || m == ORDWR || m == OMASK)
 			a->id = subscribe(a->q);
 		r->fid->aux = a;
@@ -497,4 +514,5 @@
 	}ARGEND;
 
 	postmountsrv(&mq, srvname, mntpt, MCREATE|MREPL);
+	exits(nil);
 }