diff options
| author | Paul Eggert | 2017-05-01 15:33:06 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-05-01 15:33:26 -0700 |
| commit | 634d0a907ff7ba5901dfe3624e58d718f3f37cec (patch) | |
| tree | 6bf86cf04d8b28a79693df9cdef1063c9b06ca76 /lib/utimens.c | |
| parent | 16b49e214ad828de29ceb57ad1b443eece9bba03 (diff) | |
| download | emacs-634d0a907ff7ba5901dfe3624e58d718f3f37cec.tar.gz emacs-634d0a907ff7ba5901dfe3624e58d718f3f37cec.zip | |
Merge from gnulib
This incorporates:
2017-05-01 New module 'localtime-buffer'
2017-04-30 utimens: Add support for native Windows
* admin/merge-gnulib (AVOIDED_MODULES): Add tzset.
* configure.ac (tzset): No need for Emacs itself to check now.
* lib/gettimeofday.c, lib/time.in.h, lib/time_rz.c, lib/utimens.c:
* m4/gettimeofday.m4, m4/time_h.m4, m4/time_rz.m4: Copy from gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib/localtime-buffer.c, lib/localtime-buffer.h:
* m4/localtime-buffer.m4: New files, copied from gnulib.
* src/editfns.c (init_editfns): Assume tzset is callable.
Diffstat (limited to 'lib/utimens.c')
| -rw-r--r-- | lib/utimens.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/lib/utimens.c b/lib/utimens.c index 3b451193350..0b3b8e2f3af 100644 --- a/lib/utimens.c +++ b/lib/utimens.c | |||
| @@ -35,6 +35,12 @@ | |||
| 35 | #include "stat-time.h" | 35 | #include "stat-time.h" |
| 36 | #include "timespec.h" | 36 | #include "timespec.h" |
| 37 | 37 | ||
| 38 | #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | ||
| 39 | # define WIN32_LEAN_AND_MEAN | ||
| 40 | # include <windows.h> | ||
| 41 | # include "msvc-nothrow.h" | ||
| 42 | #endif | ||
| 43 | |||
| 38 | /* Avoid recursion with rpl_futimens or rpl_utimensat. */ | 44 | /* Avoid recursion with rpl_futimens or rpl_utimensat. */ |
| 39 | #undef futimens | 45 | #undef futimens |
| 40 | #undef utimensat | 46 | #undef utimensat |
| @@ -271,6 +277,82 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) | |||
| 271 | lutimensat_works_really = -1; | 277 | lutimensat_works_really = -1; |
| 272 | #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ | 278 | #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ |
| 273 | 279 | ||
| 280 | #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | ||
| 281 | /* On native Windows, use SetFileTime(). See | ||
| 282 | <https://msdn.microsoft.com/en-us/library/ms724933.aspx> | ||
| 283 | <https://msdn.microsoft.com/en-us/library/ms724284.aspx> */ | ||
| 284 | if (0 <= fd) | ||
| 285 | { | ||
| 286 | HANDLE handle; | ||
| 287 | FILETIME current_time; | ||
| 288 | FILETIME last_access_time; | ||
| 289 | FILETIME last_write_time; | ||
| 290 | |||
| 291 | handle = (HANDLE) _get_osfhandle (fd); | ||
| 292 | if (handle == INVALID_HANDLE_VALUE) | ||
| 293 | { | ||
| 294 | errno = EBADF; | ||
| 295 | return -1; | ||
| 296 | } | ||
| 297 | |||
| 298 | if (ts == NULL || ts[0].tv_nsec == UTIME_NOW || ts[1].tv_nsec == UTIME_NOW) | ||
| 299 | { | ||
| 300 | /* GetSystemTimeAsFileTime | ||
| 301 | <https://msdn.microsoft.com/en-us/library/ms724397.aspx>. | ||
| 302 | It would be overkill to use | ||
| 303 | GetSystemTimePreciseAsFileTime | ||
| 304 | <https://msdn.microsoft.com/en-us/library/hh706895.aspx>. */ | ||
| 305 | GetSystemTimeAsFileTime (¤t_time); | ||
| 306 | } | ||
| 307 | |||
| 308 | if (ts == NULL || ts[0].tv_nsec == UTIME_NOW) | ||
| 309 | { | ||
| 310 | last_access_time = current_time; | ||
| 311 | } | ||
| 312 | else if (ts[0].tv_nsec == UTIME_OMIT) | ||
| 313 | { | ||
| 314 | last_access_time.dwLowDateTime = 0; | ||
| 315 | last_access_time.dwHighDateTime = 0; | ||
| 316 | } | ||
| 317 | else | ||
| 318 | { | ||
| 319 | ULONGLONG time_since_16010101 = | ||
| 320 | (ULONGLONG) ts[0].tv_sec * 10000000 + ts[0].tv_nsec / 100 + 116444736000000000LL; | ||
| 321 | last_access_time.dwLowDateTime = (DWORD) time_since_16010101; | ||
| 322 | last_access_time.dwHighDateTime = time_since_16010101 >> 32; | ||
| 323 | } | ||
| 324 | |||
| 325 | if (ts == NULL || ts[1].tv_nsec == UTIME_NOW) | ||
| 326 | { | ||
| 327 | last_write_time = current_time; | ||
| 328 | } | ||
| 329 | else if (ts[1].tv_nsec == UTIME_OMIT) | ||
| 330 | { | ||
| 331 | last_write_time.dwLowDateTime = 0; | ||
| 332 | last_write_time.dwHighDateTime = 0; | ||
| 333 | } | ||
| 334 | else | ||
| 335 | { | ||
| 336 | ULONGLONG time_since_16010101 = | ||
| 337 | (ULONGLONG) ts[1].tv_sec * 10000000 + ts[1].tv_nsec / 100 + 116444736000000000LL; | ||
| 338 | last_write_time.dwLowDateTime = (DWORD) time_since_16010101; | ||
| 339 | last_write_time.dwHighDateTime = time_since_16010101 >> 32; | ||
| 340 | } | ||
| 341 | |||
| 342 | if (SetFileTime (handle, NULL, &last_access_time, &last_write_time)) | ||
| 343 | return 0; | ||
| 344 | else | ||
| 345 | { | ||
| 346 | #if 0 | ||
| 347 | DWORD sft_error = GetLastError (); | ||
| 348 | fprintf (stderr, "utime SetFileTime error 0x%x\n", (unsigned int) sft_error); | ||
| 349 | #endif | ||
| 350 | errno = EINVAL; | ||
| 351 | return -1; | ||
| 352 | } | ||
| 353 | } | ||
| 354 | #endif | ||
| 355 | |||
| 274 | /* The platform lacks an interface to set file timestamps with | 356 | /* The platform lacks an interface to set file timestamps with |
| 275 | nanosecond resolution, so do the best we can, discarding any | 357 | nanosecond resolution, so do the best we can, discarding any |
| 276 | fractional part of the timestamp. */ | 358 | fractional part of the timestamp. */ |