shithub: riscv

Download patch

ref: 9619a621ac8b9be2b38790d21fc5f0c482cd83fa
parent: bcad0cd4e631ef321dca17ffa49c8ecdd30cb652
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sat Nov 2 20:34:35 EDT 2013

rio: cleanup and error handling

--- a/sys/src/cmd/rio/dat.h
+++ b/sys/src/cmd/rio/dat.h
@@ -24,6 +24,7 @@
 };
 
 #define	STACK	8192
+#define	MAXSNARF	100*1024
 
 typedef	struct	Consreadmesg Consreadmesg;
 typedef	struct	Conswritemesg Conswritemesg;
--- a/sys/src/cmd/rio/fsys.c
+++ b/sys/src/cmd/rio/fsys.c
@@ -13,8 +13,9 @@
 char Eperm[] = "permission denied";
 char Eexist[] = "file does not exist";
 char Enotdir[] = "not a directory";
-char	Ebadfcall[] = "bad fcall type";
-char	Eoffset[] = "illegal offset";
+char Ebadfcall[] = "bad fcall type";
+char Eoffset[] = "illegal offset";
+char Enomem[] = "out of memory";
 
 int	messagesize = 8192+IOHDRSZ;	/* good start */
 
@@ -192,7 +193,9 @@
 	fs->pid = getpid();
 	x = nil;
 	for(;;){
-		buf = emalloc(messagesize+UTFmax);	/* UTFmax for appending partial rune in xfidwrite */
+		buf = malloc(messagesize+UTFmax);	/* UTFmax for appending partial rune in xfidwrite */
+		if(buf == nil)
+			error(Enomem);
 		while((n = read9pmsg(fs->sfd, buf, messagesize)) == 0)
 			yield();
 		if(n < 0){
@@ -259,7 +262,7 @@
 	t->fid = x->fid;
 	t->tag = x->tag;
 	if(x->buf == nil)
-		x->buf = malloc(messagesize);
+		error("no buffer in respond");
 	n = convS2M(t, x->buf, messagesize);
 	if(n <= 0)
 		error("convert error in convS2M");
@@ -556,7 +559,7 @@
 	clock = getclock();
 	b = malloc(messagesize-IOHDRSZ);	/* avoid memset of emalloc */
 	if(b == nil)
-		return filsysrespond(fs, x, &t, "out of memory");
+		return filsysrespond(fs, x, &t, Enomem);
 	n = 0;
 	switch(FILE(f->qid)){
 	case Qdir:
--- a/sys/src/cmd/rio/rio.c
+++ b/sys/src/cmd/rio/rio.c
@@ -270,7 +270,7 @@
 getsnarf(void)
 {
 	int i, n, nb, nulls;
-	char *sn, buf[1024];
+	char *s, *sn;
 
 	if(snarffd < 0)
 		return;
@@ -277,17 +277,22 @@
 	sn = nil;
 	i = 0;
 	seek(snarffd, 0, 0);
-	while((n = read(snarffd, buf, sizeof buf)) > 0){
-		sn = erealloc(sn, i+n+1);
-		memmove(sn+i, buf, n);
+	for(;;){
+		if(i > MAXSNARF)
+			break;
+		if((s = realloc(sn, i+1024+1)) == nil)
+			break;
+		sn = s;
+		if((n = read(snarffd, sn+i, 1024)) <= 0)
+			break;
 		i += n;
-		sn[i] = 0;
 	}
-	if(i > 0){
-		snarf = runerealloc(snarf, i+1);
+	if(i == 0)
+		return;
+	sn[i] = 0;
+	if((snarf = runerealloc(snarf, i+1)) != nil)
 		cvttorunes(sn, i, snarf, &nb, &nsnarf, &nulls);
-		free(sn);
-	}
+	free(sn);
 }
 
 void
@@ -365,16 +370,15 @@
 	if(s[cnt-1] == 0)
 		chanprint(kbdchan, "%s", s);
 	else {
-		Rune *r;
-		int i, nb, nr;
+		Rune r;
+		int nb;
 
-		r = runemalloc(cnt);
-		cvttorunes(s, cnt, r, &nb, &nr, nil);
-		for(i=0; i<nr; i++){
-			if(r[i])
-				chanprint(kbdchan, "c%C", r[i]);
+		nb = 0;
+		while(fullrune(s+nb, cnt-nb)){
+			nb += chartorune(&r, s+nb);
+			if(r != 0)
+				chanprint(kbdchan, "c%C", r);
 		}
-		free(r);
 	}
 }
 
--- a/sys/src/cmd/rio/util.c
+++ b/sys/src/cmd/rio/util.c
@@ -58,6 +58,7 @@
 	p = realloc(p, n);
 	if(p == nil)
 		error("realloc failed");
+	setrealloctag(p, getcallerpc(&p));
 	return p;
 }
 
@@ -69,6 +70,7 @@
 	p = malloc(n);
 	if(p == nil)
 		error("malloc failed");
+	setmalloctag(p, getcallerpc(&n));
 	memset(p, 0, n);
 	return p;
 }
--- a/sys/src/cmd/rio/wind.c
+++ b/sys/src/cmd/rio/wind.c
@@ -435,11 +435,13 @@
 					showcandidates(w, cr);
 				if(cr->advance){
 					rp = runesmprint("%s", cr->string);
-					nr = runestrlen(rp);
-					q0 = w->q0;
-					q0 = winsert(w, rp, nr, q0);
-					wshow(w, q0+nr);
-					free(rp);
+					if(rp){
+						nr = runestrlen(rp);
+						q0 = w->q0;
+						q0 = winsert(w, rp, nr, q0);
+						wshow(w, q0+nr);
+						free(rp);
+					}
 				}
 			}
 			freecompletion(cr);
@@ -582,21 +584,19 @@
 	runemove(path, w->r+(w->q0-nstr-npath), npath);
 
 	/* is path rooted? if not, we need to make it relative to window path */
-	if(npath>0 && path[0]=='/'){
-		dir = malloc(UTFmax*npath+1);
-		sprint(dir, "%.*S", npath, path);
-	}else{
+	if(npath>0 && path[0]=='/')
+		dir = runetobyte(path, npath, &npath);
+	else {
 		if(strcmp(w->dir, "") == 0)
 			root = ".";
 		else
 			root = w->dir;
-		dir = malloc(strlen(root)+1+UTFmax*npath+1);
-		sprint(dir, "%s/%.*S", root, npath, path);
+		dir = smprint("%s/%.*S", root, npath, path);
 	}
 
 	/* run in background, winctl will collect the result on w->complete chan */
 	job = emalloc(sizeof *job);
-	job->str = smprint("%.*S", nstr, str);
+	job->str = runetobyte(str, nstr, &nstr);
 	job->dir = cleanname(dir);
 	job->win = w;
 	incref(w);
--- a/sys/src/cmd/rio/xfid.c
+++ b/sys/src/cmd/rio/xfid.c
@@ -11,13 +11,9 @@
 #include "dat.h"
 #include "fns.h"
 
-#define	MAXSNARF	100*1024
-
 char Einuse[] =		"file in use";
 char Edeleted[] =	"window deleted";
-char Ebadreq[] =	"bad graphics request";
 char Etooshort[] =	"buffer too small";
-char Ebadtile[] =	"unknown tile";
 char Eshort[] =		"short i/o request";
 char Elong[] = 		"snarf buffer too long";
 char Eunkid[] = 	"unknown id in attach";
@@ -25,9 +21,9 @@
 char Ewindow[] = 	"cannot make window";
 char Enowindow[] = 	"window has no image";
 char Ebadmouse[] = 	"bad format on /dev/mouse";
-char Ebadwrect[] = 	"rectangle outside screen";
-char Ebadoffset[] = 	"window read not on scan line boundary";
+
 extern char Eperm[];
+extern char Enomem[];
 
 static	Xfid	*xfidfree;
 static	Xfid	*xfid;
@@ -292,12 +288,8 @@
 		w->mouseopen = TRUE;
 		break;
 	case Qsnarf:
-		if(x->mode==ORDWR || x->mode==OWRITE){
-			if(tsnarf)
-				free(tsnarf);	/* collision, but OK */
+		if(x->mode==ORDWR || x->mode==OWRITE)
 			ntsnarf = 0;
-			tsnarf = malloc(1);
-		}
 		break;
 	case Qwctl:
 		if(x->mode==OREAD || x->mode==ORDWR){
@@ -364,8 +356,6 @@
 		if(x->f->mode==ORDWR || x->f->mode==OWRITE){
 			snarf = runerealloc(snarf, ntsnarf+1);
 			cvttorunes(tsnarf, ntsnarf, snarf, &nb, &nsnarf, &nulls);
-			free(tsnarf);
-			tsnarf = nil;
 			ntsnarf = 0;
 		}
 		break;
@@ -382,8 +372,8 @@
 xfidwrite(Xfid *x)
 {
 	Fcall fc;
-	int c, cnt, qid, nb, off, nr;
-	char buf[256], *p;
+	int cnt, qid, nb, off, nr;
+	char err[ERRMAX], *p;
 	Point pt;
 	Window *w;
 	Rune *r;
@@ -403,28 +393,7 @@
 	x->data[cnt] = 0;
 	switch(qid){
 	case Qcons:
-		nr = x->f->nrpart;
-		if(nr > 0){
-			memmove(x->data+nr, x->data, cnt);	/* there's room: see malloc in filsysproc */
-			memmove(x->data, x->f->rpart, nr);
-			cnt += nr;
-			x->f->nrpart = 0;
-		}
-		r = runemalloc(cnt);
-		cvttorunes(x->data, cnt-UTFmax, r, &nb, &nr, nil);
-		/* approach end of buffer */
-		while(fullrune(x->data+nb, cnt-nb)){
-			c = nb;
-			nb += chartorune(&r[nr], x->data+c);
-			if(r[nr])
-				nr++;
-		}
-		if(nb < cnt){
-			memmove(x->f->rpart, x->data+nb, cnt-nb);
-			x->f->nrpart = cnt-nb;
-		}
-
-		alts[CWdata].c = w->conswrite;
+		alts[CWdata].c = w->conswrite;
 		alts[CWdata].v = &cwm;
 		alts[CWdata].op = CHANRCV;
 		alts[CWgone].c = w->gone;
@@ -440,15 +409,38 @@
 			break;
 		case CWgone:
 			filsysrespond(x->fs, x, &fc, Edeleted);
-			free(r);
 			return;
 		case CWflush:
-			free(r);
 			filsyscancel(x);
 			return;
 		}
 
-		/* received data */
+		nr = x->f->nrpart;
+		if(nr > 0){
+			memmove(x->data+nr, x->data, cnt);	/* there's room: see malloc in filsysproc */
+			memmove(x->data, x->f->rpart, nr);
+			cnt += nr;
+		}
+		r = runemalloc(cnt);
+		if(r == nil){
+			pair.ns = 0;
+			send(cwm.cw, &pair);
+			filsysrespond(x->fs, x, &fc, Enomem);
+			return;
+		}
+		x->f->nrpart = 0;
+		cvttorunes(x->data, cnt-UTFmax, r, &nb, &nr, nil);
+		/* approach end of buffer */
+		while(fullrune(x->data+nb, cnt-nb)){
+			nb += chartorune(&r[nr], x->data+nb);
+			if(r[nr])
+				nr++;
+		}
+		if(nb < cnt){
+			memmove(x->f->rpart, x->data+nb, cnt-nb);
+			x->f->nrpart = cnt-nb;
+		}
+
 		pair.s = r;
 		pair.ns = nr;
 		send(cwm.cw, &pair);
@@ -501,10 +493,14 @@
 			filsysrespond(x->fs, x, &fc, "non-zero offset writing label");
 			return;
 		}
-		free(w->label);
-		w->label = emalloc(cnt+1);
-		memmove(w->label, x->data, cnt);
+		p = realloc(w->label, cnt+1);
+		if(p == nil){
+			filsysrespond(x->fs, x, &fc, Enomem);
+			return;
+		}
+		w->label = p;
 		w->label[cnt] = 0;
+		memmove(w->label, x->data, cnt);
 		break;
 
 	case Qmouse:
@@ -526,12 +522,19 @@
 		break;
 
 	case Qsnarf:
+		if(cnt == 0)
+			break;
 		/* always append only */
 		if(ntsnarf > MAXSNARF){	/* avoid thrashing when people cut huge text */
 			filsysrespond(x->fs, x, &fc, Elong);
 			return;
 		}
-		tsnarf = erealloc(tsnarf, ntsnarf+cnt+1);	/* room for NUL */
+		p = realloc(tsnarf, ntsnarf+cnt+1);	/* room for NUL */
+		if(p == nil){
+			filsysrespond(x->fs, x, &fc, Enomem);
+			return;
+		}
+		tsnarf = p;
 		memmove(tsnarf+ntsnarf, x->data, cnt);
 		ntsnarf += cnt;
 		snarfversion++;
@@ -546,20 +549,17 @@
 			x->data[cnt-1] = '\0';
 		}
 		/* assume data comes in a single write */
-		/*
-		  * Problem: programs like dossrv, ftp produce illegal UTF;
-		  * we must cope by converting it first.
-		  */
-		snprint(buf, sizeof buf, "%.*s", cnt, x->data);
-		if(buf[0] == '/'){
-			free(w->dir);
-			w->dir = estrdup(buf);
+		if(x->data[0] == '/'){
+			p = smprint("%.*s", cnt, x->data);
 		}else{
-			p = emalloc(strlen(w->dir) + 1 + strlen(buf) + 1);
-			sprint(p, "%s/%s", w->dir, buf);
-			free(w->dir);
-			w->dir = cleanname(p);
+			p = smprint("%s/%.*s", w->dir, cnt, x->data);
 		}
+		if(p == nil){
+			filsysrespond(x->fs, x, &fc, Enomem);
+			return;
+		}
+		free(w->dir);
+		w->dir = cleanname(p);
 		break;
 
 	case Qkbdin:
@@ -567,8 +567,8 @@
 		break;
 
 	case Qwctl:
-		if(writewctl(x, buf) < 0){
-			filsysrespond(x->fs, x, &fc, buf);
+		if(writewctl(x, err) < 0){
+			filsysrespond(x->fs, x, &fc, err);
 			return;
 		}
 		break;
@@ -575,8 +575,7 @@
 
 	default:
 		fprint(2, "unknown qid %d in write\n", qid);
-		snprint(buf, sizeof(buf), "unknown qid in write");
-		filsysrespond(x->fs, x, &fc, buf);
+		filsysrespond(x->fs, x, &fc, "unknown qid in write");
 		return;
 	}
 	fc.count = cnt;
@@ -653,7 +652,7 @@
 		alts[CRflush].c = x->flushc;
 		alts[CRflush].v = nil;
 		alts[CRflush].op = CHANRCV;
-		alts[NMR].op = CHANEND;
+		alts[NCR].op = CHANEND;
 
 		switch(alt(alts)){
 		case CRdata:
@@ -666,7 +665,6 @@
 			return;
 		}
 
-		/* received data */
 		c1 = crm.c1;
 		c2 = crm.c2;
 		t = malloc(cnt+UTFmax+1);	/* room to unpack partial rune plus */
@@ -713,6 +711,7 @@
 			filsyscancel(x);
 			return;
 		}
+
 		recv(mrm.cm, &ms);
 		c = 'm';
 		if(w->resized)
@@ -747,7 +746,6 @@
 			return;
 		}
 
-		/* received data */
 		t = recvp(krm.ck);
 		fc.data = t;
 		fc.count = strlen(t)+1;
@@ -829,9 +827,12 @@
 			goto Text;
 		}
 		off -= 5*12;
+		n = -1;
 		t = malloc(cnt);
-		fc.data = t;
-		n = readwindow(i, t, r, off, cnt);	/* careful; fc.count is unsigned */
+		if(t){
+			fc.data = t;
+			n = readwindow(i, t, r, off, cnt);	/* careful; fc.count is unsigned */
+		}
 		if(n < 0){
 			buf[0] = 0;
 			errstr(buf, sizeof buf);
@@ -858,7 +859,7 @@
 		alts[WCRflush].c = x->flushc;
 		alts[WCRflush].v = nil;
 		alts[WCRflush].op = CHANRCV;
-		alts[NMR].op = CHANEND;
+		alts[NWCR].op = CHANEND;
 
 		switch(alt(alts)){
 		case WCRdata:
@@ -871,7 +872,6 @@
 			return;
 		}
 
-		/* received data */
 		c1 = cwrm.c1;
 		c2 = cwrm.c2;
 		t = malloc(cnt+1);	/* be sure to have room for NUL */
--