summaryrefslogtreecommitdiff
path: root/lib/libarchive/archive_write_disk.c
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@FreeBSD.org>2009-03-03 17:02:51 +0000
committerTim Kientzle <kientzle@FreeBSD.org>2009-03-03 17:02:51 +0000
commit690f818afd6c3c0721202dd1e075aeaaae004704 (patch)
tree1dee8b4b9c023077ab174a6dc9ffbb460e86b36b /lib/libarchive/archive_write_disk.c
parent6b0ff427a57b12372e9b7181e92e50b17c773ca9 (diff)
Notes
Diffstat (limited to 'lib/libarchive/archive_write_disk.c')
-rw-r--r--lib/libarchive/archive_write_disk.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c
index ddac6302e0eb..448d92e91a11 100644
--- a/lib/libarchive/archive_write_disk.c
+++ b/lib/libarchive/archive_write_disk.c
@@ -83,6 +83,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
+#ifdef _WIN32
+#include <windows.h>
+#endif
#include "archive.h"
#include "archive_string.h"
@@ -516,6 +519,9 @@ static ssize_t
write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
{
uint64_t start_size = size;
+#if _WIN32
+ HANDLE handle;
+#endif
ssize_t bytes_written = 0;
ssize_t block_size = 0, bytes_to_write;
@@ -524,6 +530,9 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
"Attempt to write to an empty file");
return (ARCHIVE_WARN);
}
+#if _WIN32
+ handle = (HANDLE)_get_osfhandle(a->fd);
+#endif
if (a->flags & ARCHIVE_EXTRACT_SPARSE) {
#if HAVE_STRUCT_STAT_ST_BLKSIZE
@@ -572,7 +581,23 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
if (a->offset + bytes_to_write > block_end)
bytes_to_write = block_end - a->offset;
}
-
+#ifdef _WIN32
+ /* Seek if necessary to the specified offset. */
+ if (offset != a->fd_offset) {
+ LARGE_INTEGER distance;
+ distance.QuadPart = offset;
+ if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN)) {
+ archive_set_error(&a->archive, _dosmaperr(GetLastError()),
+ "Seek failed");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ if (!WriteFile(handle, buff, bytes_to_write, &bytes_written, NULL)) {
+ archive_set_error(&a->archive, _dosmaperr(GetLastError()),
+ "Write failed");
+ return (ARCHIVE_WARN);
+ }
+#else
/* Seek if necessary to the specified offset. */
if (a->offset != a->fd_offset) {
if (lseek(a->fd, a->offset, SEEK_SET) < 0) {
@@ -589,6 +614,7 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
archive_set_error(&a->archive, errno, "Write failed");
return (ARCHIVE_WARN);
}
+#endif
buff += bytes_written;
size -= bytes_written;
a->offset += bytes_written;
@@ -1186,7 +1212,11 @@ _archive_write_close(struct archive *_a)
if (p->fixup & TODO_TIMES) {
#ifdef HAVE_UTIMES
/* {f,l,}utimes() are preferred, when available. */
+#ifdef __timeval
+ struct __timeval times[2];
+#else
struct timeval times[2];
+#endif
times[0].tv_sec = p->atime;
times[0].tv_usec = p->atime_nanos / 1000;
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
@@ -1717,7 +1747,11 @@ set_time(int fd, int mode, const char *name,
time_t atime, long atime_nsec,
time_t mtime, long mtime_nsec)
{
+#ifdef __timeval
+ struct __timeval times[2];
+#else
struct timeval times[2];
+#endif
times[0].tv_sec = atime;
times[0].tv_usec = atime_nsec / 1000;