aboutsummaryrefslogtreecommitdiffstats
path: root/lib/utimens.c
diff options
context:
space:
mode:
authorPaul Eggert2017-05-01 15:33:06 -0700
committerPaul Eggert2017-05-01 15:33:26 -0700
commit634d0a907ff7ba5901dfe3624e58d718f3f37cec (patch)
tree6bf86cf04d8b28a79693df9cdef1063c9b06ca76 /lib/utimens.c
parent16b49e214ad828de29ceb57ad1b443eece9bba03 (diff)
downloademacs-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.c82
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 (&current_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. */