mirror of
https://github.com/curl/curl.git
synced 2026-08-05 16:16:14 +03:00
tool_operate: Fix --remote-time incorrect times on Windows
- Use Windows API SetFileTime to set the file time instead of utime. Avoid utime on Windows if possible because it may apply a daylight saving time offset to our UTC file time. Bug: https://curl.haxx.se/mail/archive-2016-11/0033.html Reported-by: Tim Closes https://github.com/curl/curl/pull/1121
This commit is contained in:
parent
89b7898846
commit
ee3c83f39c
2 changed files with 54 additions and 7 deletions
|
|
@ -1727,20 +1727,65 @@ static CURLcode operate_do(struct GlobalConfig *global,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UTIME
|
||||
#if defined(HAVE_UTIME) || \
|
||||
(defined(WIN32) && (CURL_SIZEOF_CURL_OFF_T >= 8))
|
||||
/* File time can only be set _after_ the file has been closed */
|
||||
if(!result && config->remote_time && outs.s_isreg && outs.filename) {
|
||||
/* Ask libcurl if we got a remote file time */
|
||||
long filetime = -1;
|
||||
curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
|
||||
if(filetime >= 0) {
|
||||
/* Windows utime() may attempt to adjust our unix gmt 'filetime' by a daylight
|
||||
saving time offset and since it's GMT that is bad behavior. When we have
|
||||
access to a 64-bit type we can bypass utime and set the times directly. */
|
||||
#if defined(WIN32) && (CURL_SIZEOF_CURL_OFF_T >= 8)
|
||||
/* 910670515199 is the maximum unix filetime that can be used as a
|
||||
Windows FILETIME without overflow: 30827-12-31T23:59:59. */
|
||||
if(filetime <= CURL_OFF_T_C(910670515199)) {
|
||||
HANDLE hfile = CreateFileA(outs.filename, FILE_WRITE_ATTRIBUTES,
|
||||
(FILE_SHARE_READ | FILE_SHARE_WRITE |
|
||||
FILE_SHARE_DELETE),
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if(hfile != INVALID_HANDLE_VALUE) {
|
||||
curl_off_t converted = ((curl_off_t)filetime * 10000000) +
|
||||
CURL_OFF_T_C(116444736000000000);
|
||||
FILETIME ft;
|
||||
ft.dwLowDateTime = (DWORD)(converted & 0xFFFFFFFF);
|
||||
ft.dwHighDateTime = (DWORD)(converted >> 32);
|
||||
if(!SetFileTime(hfile, NULL, &ft, &ft)) {
|
||||
fprintf(config->global->errors,
|
||||
"Failed to set filetime %ld on outfile: "
|
||||
"SetFileTime failed: GetLastError %u\n",
|
||||
filetime, GetLastError());
|
||||
}
|
||||
CloseHandle(hfile);
|
||||
}
|
||||
else {
|
||||
fprintf(config->global->errors,
|
||||
"Failed to set filetime %ld on outfile: "
|
||||
"CreateFile failed: GetLastError %u\n",
|
||||
filetime, GetLastError());
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(config->global->errors,
|
||||
"Failed to set filetime %ld on outfile: overflow\n",
|
||||
filetime);
|
||||
}
|
||||
#elif defined(HAVE_UTIME)
|
||||
struct utimbuf times;
|
||||
times.actime = (time_t)filetime;
|
||||
times.modtime = (time_t)filetime;
|
||||
utime(outs.filename, ×); /* set the time we got */
|
||||
if(utime(outs.filename, ×)) {
|
||||
fprintf(config->global->errors,
|
||||
"Failed to set filetime %ld on outfile: errno %d\n",
|
||||
filetime, errno);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(HAVE_UTIME) || \
|
||||
(defined(WIN32) && (CURL_SIZEOF_CURL_OFF_T >= 8)) */
|
||||
|
||||
#ifdef USE_METALINK
|
||||
if(!metalink && config->use_metalink && result == CURLE_OK) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue