aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toys/posix/tar.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/toys/posix/tar.c b/toys/posix/tar.c
index 49b1aa1f..1cece411 100644
--- a/toys/posix/tar.c
+++ b/toys/posix/tar.c
@@ -311,15 +311,23 @@ static int add_to_tar(struct dirtree *node)
// Enumerate the extents
while ((lo = lseek(fd, ld, SEEK_HOLE)) != -1) {
if (!(TT.sparselen&511))
- TT.sparse = xrealloc(TT.sparse, (TT.sparselen+512)*sizeof(long long));
+ TT.sparse = xrealloc(TT.sparse, (TT.sparselen+514)*sizeof(long long));
TT.sparse[TT.sparselen++] = ld;
len += TT.sparse[TT.sparselen++] = lo-ld;
- if (lo == st->st_size) break;
+ if (lo == st->st_size) {
+ if (TT.sparselen == 2) TT.sparselen = 0;
+ else {
+ // Gratuitous extra entry for compatibility with other versions
+ TT.sparse[TT.sparselen++] = lo;
+ TT.sparse[TT.sparselen++] = 0;
+ }
+ break;
+ }
if ((ld = lseek(fd, lo, SEEK_DATA)) < lo) ld = st->st_size;
}
// If there were extents, change type to S record
- if (TT.sparselen>2) {
+ if (TT.sparselen) {
hdr.type = 'S';
lnk = (char *)&hdr;
for (i = 0; i<TT.sparselen && i<8; i++)