shithub: riscv

Download patch

ref: 77611280935dfbd7b976fd9340bf8593bf4320f1
parent: 4fd55abb8e6dc11b257699cbd095fa5ef60e1ece
author: cinap_lenrek <[email protected]>
date: Sat Dec 7 02:17:32 EST 2013

devproc: make sure /proc/n/wait waits for the right process children

theres a race when we wait for a process children and that
process exits before we sleep().

--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -680,12 +680,23 @@
 	return tproduced > tconsumed;
 }
 
+static int
+prochaswaitq(void *x)
+{
+	Chan *c;
+	Proc *p;
+
+	c = (Chan *)x;
+	p = proctab(SLOT(c->qid));
+	return p->pid != PID(c->qid) || p->waitq != 0;
+}
+
 static long
 procread(Chan *c, void *va, long n, vlong off)
 {
 	/* NSEG*32 was too small for worst cases */
 	char *a, flag[10], *sps, *srv, statbuf[NSEG*64];
-	int i, j, m, navail, ne, pid, rsize;
+	int i, j, m, navail, ne, rsize;
 	long l;
 	uchar *rptr;
 	ulong offset;
@@ -924,18 +935,19 @@
 		}
 
 		lock(&p->exl);
-		pid = p->pid;
-		while(p->waitq == 0) {
+		while(p->waitq == 0 && p->pid == PID(c->qid)) {
 			if(up == p && p->nchild == 0) {
 				unlock(&p->exl);
 				error(Enochild);
 			}
 			unlock(&p->exl);
-			sleep(&p->waitr, haswaitq, p);
-			if(p->pid != pid)
-				error(Eprocdied);
+			sleep(&p->waitr, prochaswaitq, c);
 			lock(&p->exl);
 		}
+		if(p->pid != PID(c->qid)){
+			unlock(&p->exl);
+			error(Eprocdied);
+		}
 		wq = p->waitq;
 		p->waitq = wq->next;
 		p->nwait--;
@@ -1229,11 +1241,12 @@
 		error(Einuse);
 	if(procstopped(p) || p->state == Broken)
 		return;
-
+	pid = p->pid;
+	if(pid == 0)
+		error(Eprocdied);
 	if(ctl != 0)
 		p->procctl = ctl;
 	p->pdbg = up;
-	pid = p->pid;
 	qunlock(&p->debug);
 	up->psstate = "Stopwait";
 	if(waserror()) {
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -124,7 +124,6 @@
 ulong		getrealloctag(void*);
 void		gotolabel(Label*);
 char*		getconfenv(void);
-int		haswaitq(void*);
 long		hostdomainwrite(char*, int);
 long		hostownerwrite(char*, int);
 void		hzsched(void);
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -1205,7 +1205,7 @@
 	panic("pexit");
 }
 
-int
+static int
 haswaitq(void *x)
 {
 	Proc *p;