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);