shithub: riscv

Download patch

ref: 0c705580ab670e94b3a792967b428ad841ce570f
parent: 7b7c7f4451563693da8dc045e427dba0a9490792
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Mar 7 10:21:01 EST 2015

snap: fix readseg() to cope with > 2gb segments

--- a/sys/src/cmd/snap/snap.h
+++ b/sys/src/cmd/snap/snap.h
@@ -26,9 +26,9 @@
 struct Seg {
 	char*	name;
 	uvlong	offset;
-	uvlong	 len;
+	uvlong	len;
 	Page**	pg;
-	int	npg;
+	ulong	npg;
 };
 
 struct Page {
--- a/sys/src/cmd/snap/take.c
+++ b/sys/src/cmd/snap/take.c
@@ -96,47 +96,45 @@
 }
 
 static Seg*
-readseg(int fd, vlong off, ulong len, char *name)
+readseg(int fd, uvlong off, uvlong len, char *name)
 {
 	char buf[Pagesize];
+	ulong npg;
 	Page **pg;
-	int npg;
 	Seg *s;
-	ulong i;
 	int n;
 
 	s = emalloc(sizeof(*s));
 	s->name = estrdup(name);
-
 	if(seek(fd, off, 0) < 0) {
 		fprint(2, "seek fails\n");
 		goto Die;
 	}
-
+	s->offset = off;
+	s->len = 0;
 	pg = nil;
 	npg = 0;
-	for(i=0; i<len; ) {
+	while(s->len < len){
 		n = Pagesize;
-		if(n > len-i)
-			n = len-i;
+		if(n > len - s->len)
+			n = len - s->len;
 		if((n = readn(fd, buf, n)) <= 0)
 			break;
-		pg = erealloc(pg, sizeof(*pg)*(npg+1));
+		s->len += n;
+		if((npg & (npg-1)) == 0)
+			pg = erealloc(pg, sizeof(*pg) * (npg==0 | npg*2));
 		pg[npg++] = datapage(buf, n);
-		i += n;
 		if(n != Pagesize)	/* any short read, planned or otherwise */
 			break;
 	}
-
-	if(i==0 && len!=0)
+	if(s->len==0 && len!=0){
+		free(pg);
 		goto Die;
-
-	s->offset = off;
-	s->len = i;
+	}
+	pg = erealloc(pg, sizeof(*pg) * npg);
 	s->pg = pg;
 	s->npg = npg;
 	return s;
-
 Die:
 	free(s->name);
 	free(s);