From da286857e084c98caf151629177fa1fcd7d087fc Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 20 Feb 2012 17:11:13 +0100 Subject: [PATCH] windows: add utimes implementation --- ConfigureChecks.cmake | 2 ++ config.h.cmake | 3 +- src/std/c_time.c | 72 +++++++++++++++++++++++++++++++++++++++ src/std/c_time.h | 3 ++ src/vio/csync_vio_local.c | 3 +- 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index d08d2d418..eda34361a 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -48,4 +48,6 @@ endif() check_function_exists(strerror_r HAVE_STRERROR_R) +check_function_exists(utimes HAVE_UTIMES) + set(CSYNC_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "csync required system libraries") diff --git a/config.h.cmake b/config.h.cmake index b4c1405b9..ff7321c4c 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -11,4 +11,5 @@ #cmakedefine HAVE_CLOCK_GETTIME #cmakedefine WITH_LOG4C 1 -#cmakedefine HAVE_STRERROR_R \ No newline at end of file +#cmakedefine HAVE_STRERROR_R +#cmakedefine HAVE_UTIMES diff --git a/src/std/c_time.c b/src/std/c_time.c index 270ff7823..84cfa1ffe 100644 --- a/src/std/c_time.c +++ b/src/std/c_time.c @@ -63,3 +63,75 @@ double c_secdiff(struct timespec clock1, struct timespec clock0) { return ret; } + +#ifdef HAVE_UTIMES +int c_utimes(const char *uri, const struct timeval *times) { + return utimes(uri, times); +} +#else // HAVE_UTIMES + +#ifdef _WIN32 +// implementation for utimes taken from KDE mingw headers + +#include +#include +#define CSYNC_SECONDS_SINCE_1601 11644473600LL +#define CSYNC_USEC_IN_SEC 1000000LL +//after Microsoft KB167296 +static void UnixTimevalToFileTime(struct timeval t, LPFILETIME pft) +{ + LONGLONG ll; + ll = Int32x32To64(t.tv_sec, CSYNC_USEC_IN_SEC*10) + t.tv_usec*10 + CSYNC_SECONDS_SINCE_1601*CSYNC_USEC_IN_SEC*10; + pft->dwLowDateTime = (DWORD)ll; + pft->dwHighDateTime = ll >> 32; +} + +int c_utimes(const char *uri, const struct timeval *times) { + FILETIME LastAccessTime; + FILETIME LastModificationTime; + HANDLE hFile; + + if(times) { + UnixTimevalToFileTime(times[0], &LastAccessTime); + UnixTimevalToFileTime(times[1], &LastModificationTime); + } + else { + GetSystemTimeAsFileTime(&LastAccessTime); + GetSystemTimeAsFileTime(&LastModificationTime); + } + + hFile=CreateFileA(uri, FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if(hFile==INVALID_HANDLE_VALUE) { + switch(GetLastError()) { + case ERROR_FILE_NOT_FOUND: + errno=ENOENT; + break; + case ERROR_PATH_NOT_FOUND: + case ERROR_INVALID_DRIVE: + errno=ENOTDIR; + break; + /*case ERROR_WRITE_PROTECT: //CreateFile sets ERROR_ACCESS_DENIED on read-only devices + * errno=EROFS; + * break;*/ + case ERROR_ACCESS_DENIED: + errno=EACCES; + break; + default: + errno=ENOENT; //what other errors can occur? + } + + return -1; + } + + if(!SetFileTime(hFile, NULL, &LastAccessTime, &LastModificationTime)) { + //can this happen? + errno=ENOENT; + return -1; + } + + CloseHandle(hFile); + return 0; +} + +#endif // _WIN32 +#endif // HAVE_UTIMES diff --git a/src/std/c_time.h b/src/std/c_time.h index 735971b05..da9dc3631 100644 --- a/src/std/c_time.h +++ b/src/std/c_time.h @@ -24,6 +24,7 @@ #define _C_TIME_H #include +#include /** * @brief Calculate time difference @@ -52,4 +53,6 @@ struct timespec c_tspecdiff(struct timespec time1, struct timespec time0); */ double c_secdiff(struct timespec clock1, struct timespec clock0); +int c_utimes(const char *uri, const struct timeval *times); + #endif /* _C_TIME_H */ diff --git a/src/vio/csync_vio_local.c b/src/vio/csync_vio_local.c index 7a9e6def7..fcef78273 100644 --- a/src/vio/csync_vio_local.c +++ b/src/vio/csync_vio_local.c @@ -357,6 +357,5 @@ int csync_vio_local_chown(const char *uri, uid_t owner, gid_t group) { } int csync_vio_local_utimes(const char *uri, const struct timeval *times) { - return utimes(uri, times); + return c_utimes(uri, times); } -