From: Michihiro NAKAJIMA Date: Tue, 2 Feb 2010 11:11:30 +0000 (-0500) Subject: Windows needs a special mark to create a sparse file. X-Git-Tag: v3.0.0a~1291 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=423bd7ec6114c39a64d2b822fac6f10643d5c463;p=thirdparty%2Flibarchive.git Windows needs a special mark to create a sparse file. SVN-Revision: 1857 --- diff --git a/libarchive/archive_write_disk.c b/libarchive/archive_write_disk.c index f61ae1759..053080d65 100644 --- a/libarchive/archive_write_disk.c +++ b/libarchive/archive_write_disk.c @@ -95,6 +95,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0 #ifdef HAVE_UTIME_H #include #endif +#ifdef HAVE_WINIOCTL_H +#include +#endif #include "archive.h" #include "archive_string.h" @@ -513,6 +516,33 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry) /* TODO: Complete this.. defer fflags from below. */ } +#if defined(_WIN32) && !defined(__CYGWIN__) + /* + * On Windows, A creating sparse file requires a special mark. + */ + if (a->fd >= 0 && archive_entry_sparse_count(entry) > 0) { + int64_t base = 0, offset, length; + int i, cnt = archive_entry_sparse_reset(entry); + int sparse = 0; + + for (i = 0; i < cnt; i++) { + archive_entry_sparse_next(entry, &offset, &length); + if (offset - base >= 4096) { + sparse = 1;/* we have a hole. */ + break; + } + base = offset + length; + } + if (sparse) { + HANDLE h = (HANDLE)_get_osfhandle(a->fd); + DWORD dmy; + /* Mark this file as sparse. */ + DeviceIoControl(h, FSCTL_SET_SPARSE, + NULL, 0, NULL, 0, &dmy, NULL); + } + } +#endif + /* We've created the object and are ready to pour data into it. */ if (ret >= ARCHIVE_WARN) a->archive.state = ARCHIVE_STATE_DATA;