From: Tim Kientzle Date: Mon, 29 Dec 2008 00:21:35 +0000 (-0500) Subject: futimes() and utimes() emulations for Windows. X-Git-Tag: v2.7.0~540 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c19a33d79723449efe7e544b8764fa180b243077;p=thirdparty%2Flibarchive.git futimes() and utimes() emulations for Windows. Submitted by: Michihiro NAKAJIMA SVN-Revision: 300 --- diff --git a/libarchive/archive_windows.c b/libarchive/archive_windows.c index 1f4d273da..579bb45ef 100644 --- a/libarchive/archive_windows.c +++ b/libarchive/archive_windows.c @@ -185,4 +185,50 @@ int fstati64 (int fd, struct _stati64 *st) return res; } +#define WINTIME(sec, usec) ((Int32x32To64(sec, 10000000) + 116444736000000000) + (usec * 10)) +static int +__hutimes(HANDLE handle, const struct __timeval *times) +{ + uint64_t wintm; + FILETIME fatime, fmtime; + + wintm = WINTIME(times[0].tv_sec, times[0].tv_usec); + fatime.dwLowDateTime = (DWORD)wintm; + fatime.dwHighDateTime = wintm >> 32; + wintm = WINTIME(times[1].tv_sec, times[1].tv_usec); + fmtime.dwLowDateTime = (DWORD)wintm; + fmtime.dwHighDateTime = wintm >> 32; + if (SetFileTime(handle, NULL, &fatime, &fmtime) == 0) { + errno = EINVAL; + return (-1); + } + return (0); +} + +int +futimes(int fd, const struct __timeval *times) +{ + + return (__hutimes((HANDLE)_get_osfhandle(fd), times)); +} + +int +utimes(const char *name, const struct __timeval *times) +{ + int ret; + HANDLE handle; + + handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + 0, NULL); + if (handle == INVALID_HANDLE_VALUE) { + errno = EINVAL; + return (-1); + } + ret = __hutimes(handle, times); + CloseHandle(handle); + return (ret); +} + + #endif /* _WIN32 */ diff --git a/libarchive/archive_windows.h b/libarchive/archive_windows.h index 5d5d2d61e..3bb7645b5 100644 --- a/libarchive/archive_windows.h +++ b/libarchive/archive_windows.h @@ -239,6 +239,17 @@ #endif /* __MINGW32__ */ #endif /* LARGE_FILES */ +#ifdef USE_WINSOCK_TIMEVAL +/* Winsock timeval has long size tv_sec. */ +#define __timeval timeval +#else +struct _timeval64i32 { + time_t tv_sec; + long tv_usec; +}; +#define __timeval _timeval64i32 +#endif + /* End of Win32 definitions. */ #ifdef __cplusplus @@ -247,6 +258,9 @@ extern "C" { extern int link (const char *from, const char *to); extern int symlink (const char *from, const char *to); +extern int _dosmaperr(unsigned long); +extern int futimes(int fd, const struct __timeval *times); +extern int utimes(const char *name, const struct __timeval *times); #ifdef __cplusplus }