diff options
Diffstat (limited to 'gnulib-tests/nap.h')
-rw-r--r-- | gnulib-tests/nap.h | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/gnulib-tests/nap.h b/gnulib-tests/nap.h index 6d46a36..a49befc 100644 --- a/gnulib-tests/nap.h +++ b/gnulib-tests/nap.h @@ -1,5 +1,5 @@ /* Assist in file system timestamp tests. - Copyright (C) 2009-2016 Free Software Foundation, Inc. + Copyright (C) 2009-2017 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,6 +22,9 @@ # include <limits.h> # include <stdbool.h> +/* Name of the witness file. */ +#define TEMPFILE BASE "nap.tmp" + /* File descriptor used for the witness file. */ static int nap_fd = -1; @@ -48,36 +51,46 @@ diff_timespec (struct timespec a, struct timespec b) return INT_MAX; } +/* If DO_WRITE, bump the modification time of the file designated by NAP_FD. + Then fetch the new STAT information of NAP_FD. */ static void -get_stat (int fd, struct stat *st, int do_write) +nap_get_stat (struct stat *st, int do_write) { if (do_write) - ASSERT (write (fd, "\n", 1) == 1); - ASSERT (fstat (fd, st) == 0); + { + ASSERT (write (nap_fd, "\n", 1) == 1); +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + /* On native Windows, the modification times are not changed until NAP_FD + is closed. See + https://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx */ + close (nap_fd); + nap_fd = open (TEMPFILE, O_RDWR, 0600); + ASSERT (nap_fd != -1); + lseek (nap_fd, 0, SEEK_END); +#endif + } + ASSERT (fstat (nap_fd, st) == 0); } /* Given a file whose descriptor is FD, see whether delaying by DELAY - nanoseconds causes a change in a file's ctime and mtime. + nanoseconds causes a change in a file's mtime. OLD_ST is the file's status, recently gotten. */ static bool -nap_works (int fd, int delay, struct stat old_st) +nap_works (int delay, struct stat old_st) { struct stat st; struct timespec delay_spec; delay_spec.tv_sec = delay / 1000000000; delay_spec.tv_nsec = delay % 1000000000; ASSERT (nanosleep (&delay_spec, 0) == 0); - get_stat (fd, &st, 1); + nap_get_stat (&st, 1); - if ( diff_timespec (get_stat_ctime (&st), get_stat_ctime (&old_st)) - && diff_timespec (get_stat_mtime (&st), get_stat_mtime (&old_st))) + if (diff_timespec (get_stat_mtime (&st), get_stat_mtime (&old_st))) return true; return false; } -#define TEMPFILE BASE "nap.tmp" - static void clear_temp_file (void) { @@ -105,21 +118,30 @@ nap (void) { atexit (clear_temp_file); ASSERT ((nap_fd = creat (TEMPFILE, 0600)) != -1); - get_stat (nap_fd, &old_st, 0); + nap_get_stat (&old_st, 0); } else { ASSERT (0 <= nap_fd); - get_stat (nap_fd, &old_st, 1); + nap_get_stat (&old_st, 1); } if (1 < delay) delay = delay / 2; /* Try half of the previous delay. */ ASSERT (0 < delay); - for ( ; delay <= 2147483647; delay = delay * 2) - if (nap_works (nap_fd, delay, old_st)) - return; + for (;;) + { + if (nap_works (delay, old_st)) + return; + if (delay <= (2147483647 - 1) / 2) + { + delay = delay * 2 + 1; + continue; + } + else + break; + } /* Bummer: even the highest nap delay didn't work. */ ASSERT (0); |