--- tar-1.15.1/src/sparse.c.vfatTruncate 2006-02-02 13:38:18.000000000 -0500 +++ tar-1.15.1/src/sparse.c 2006-02-02 14:06:37.000000000 -0500 @@ -345,6 +345,8 @@ sparse_extract_region (struct tar_sparse_file *file, size_t i) { size_t write_size; + struct stat st; + off_t oldoff; if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset)) return false; @@ -354,8 +356,20 @@ if (write_size == 0) { /* Last block of the file is a hole */ - if (file->seekable && sys_truncate (file->fd)) + if (file->seekable && sys_truncate (file->fd)) { truncate_warn (file->stat_info->orig_file_name); + + /* wrapper around ftruncate: + * ftruncate may fail to grow the size of a file with some OS and filesystem + * combinations. Linux and vfat/fat is one example. If this is the case do + * a write to grow the file to the desired length. + */ + off_t length = lseek (file->fd, (off_t) 0, SEEK_CUR); + if( (length >= 0) && (fstat( file->fd, &st ) != -1) && (st.st_size < length) ) { + lseek( file->fd, length - 1, SEEK_SET); + write( file->fd, '\0', 1); + } + } } else while (write_size > 0) {