+# include <limits.h>
+# include <stdbool.h>
+
+/* File descriptor used for the witness file. */
+static int nap_fd = -1;
+
+/* Return A - B, in ns.
+ Return 0 if the true result would be negative.
+ Return INT_MAX if the true result would be greater than INT_MAX. */
+static int
+diff_timespec (struct timespec a, struct timespec b)
+{
+ time_t as = a.tv_sec;
+ time_t bs = b.tv_sec;
+ int ans = a.tv_nsec;
+ int bns = b.tv_nsec;
+
+ if (! (bs < as || (bs == as && bns < ans)))
+ return 0;
+ if (as - bs <= INT_MAX / 1000000000)
+ {
+ int sdiff = (as - bs) * 1000000000;
+ int usdiff = ans - bns;
+ if (usdiff < INT_MAX - sdiff)
+ return sdiff + usdiff;
+ }
+ return INT_MAX;
+}
+
+static void
+get_stat (int fd, struct stat *st, int do_write)
+{
+ if (do_write)
+ ASSERT (write (fd, "\n", 1) == 1);
+ ASSERT (fstat (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.
+ OLD_ST is the file's status, recently gotten. */
+static bool
+nap_works (int fd, 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);
+
+ if ( diff_timespec (get_stat_ctime (&st), get_stat_ctime (&old_st))
+ && 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)
+{
+ if (0 <= nap_fd)
+ {
+ ASSERT (close (nap_fd) != -1);
+ ASSERT (unlink (TEMPFILE) != -1);
+ }
+}
+