diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-03-07 15:21:01 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-03-07 15:21:01 +0100 |
commit | 0c705580ab670e94b3a792967b428ad841ce570f (patch) | |
tree | 3311b7e65410e757a058a93c316c6574f5f536dc /sys/src | |
parent | 7b7c7f4451563693da8dc045e427dba0a9490792 (diff) |
snap: fix readseg() to cope with > 2gb segments
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/cmd/snap/snap.h | 4 | ||||
-rw-r--r-- | sys/src/cmd/snap/take.c | 30 |
2 files changed, 16 insertions, 18 deletions
diff --git a/sys/src/cmd/snap/snap.h b/sys/src/cmd/snap/snap.h index cc50b8a38..cc4b0e5be 100644 --- a/sys/src/cmd/snap/snap.h +++ b/sys/src/cmd/snap/snap.h @@ -26,9 +26,9 @@ struct Data { struct Seg { char* name; uvlong offset; - uvlong len; + uvlong len; Page** pg; - int npg; + ulong npg; }; struct Page { diff --git a/sys/src/cmd/snap/take.c b/sys/src/cmd/snap/take.c index c59da7c7d..80ba72eed 100644 --- a/sys/src/cmd/snap/take.c +++ b/sys/src/cmd/snap/take.c @@ -96,47 +96,45 @@ readsection(long pid, char *sec) } 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); |