From: Bruno Haible <bruno@clisp.org>
Date: Sat, 4 May 2024 14:36:06 +0000 (+0200)
Subject: readutmp, boot-time: Work around a Cygwin 3.5.3 bug.
X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=fde88b711c9b1df5b142444ac7b0bc2aa8892d3a;p=gnulib.git

readutmp, boot-time: Work around a Cygwin 3.5.3 bug.

Reported by Ken Brown <kbrown@cornell.edu> in
<https://lists.gnu.org/archive/html/bug-gnulib/2024-05/msg00035.html>.

* lib/boot-time-aux.h (get_windows_boot_time): On Cygwin, ignore
pagefile.sys if it appears to be a directory, and use another file as
a fallback.
---

diff --git a/ChangeLog b/ChangeLog
index 6b56b35d8e..4b5b9bad06 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2024-05-04  Bruno Haible  <bruno@clisp.org>
+
+	readutmp, boot-time: Work around a Cygwin 3.5.3 bug.
+	Reported by Ken Brown <kbrown@cornell.edu> in
+	<https://lists.gnu.org/archive/html/bug-gnulib/2024-05/msg00035.html>.
+	* lib/boot-time-aux.h (get_windows_boot_time): On Cygwin, ignore
+	pagefile.sys if it appears to be a directory, and use another file as
+	a fallback.
+
 2024-05-03  Collin Funk  <collin.funk1@gmail.com>
 
 	gnulib-tool.py: Fix an undefined function name (regression 2024-05-02).
diff --git a/lib/boot-time-aux.h b/lib/boot-time-aux.h
index a94cdb3f30..7f8c5405e4 100644
--- a/lib/boot-time-aux.h
+++ b/lib/boot-time-aux.h
@@ -304,19 +304,35 @@ get_windows_boot_time (struct timespec *p_boot_time)
      Instead, on Windows, the boot time can be retrieved by looking at the
      time stamp of a file that (normally) gets touched only during the boot
      process, namely C:\pagefile.sys.  */
-  const char * const boot_touched_file =
-    #if defined __CYGWIN__ && !defined _WIN32
-    /* It is more portable to use /proc/cygdrive/c than /cygdrive/c.  */
-    "/proc/cygdrive/c/pagefile.sys"
-    #else
-    "C:\\pagefile.sys"
-    #endif
-    ;
-  struct stat statbuf;
-  if (stat (boot_touched_file, &statbuf) >= 0)
+  const char * const boot_touched_files[] =
     {
-      *p_boot_time = get_stat_mtime (&statbuf);
-      return 0;
+      #if defined __CYGWIN__ && !defined _WIN32
+      /* It is more portable to use /proc/cygdrive/c than /cygdrive/c.  */
+      "/proc/cygdrive/c/pagefile.sys",
+      /* A fallback, working around a Cygwin 3.5.3 bug.  It has a modification
+         time about 1.5 minutes after the last boot; but that's better than
+         nothing.  */
+      "/proc/cygdrive/c/ProgramData/Microsoft/Windows/DeviceMetadataCache/dmrc.idx"
+      #else
+      "C:\\pagefile.sys"
+      #endif
+    };
+  for (idx_t i = 0; i < SIZEOF (boot_touched_files); i++)
+    {
+      const char *filename = boot_touched_files[i];
+      struct stat statbuf;
+      if (stat (filename, &statbuf) >= 0)
+        {
+# if defined __CYGWIN__ && !defined _WIN32
+          /* Work around a Cygwin 3.5.3 bug.
+             <https://cygwin.com/pipermail/cygwin/2024-May/255931.html>  */
+          if (!S_ISDIR (statbuf.st_mode))
+# endif
+            {
+              *p_boot_time = get_stat_mtime (&statbuf);
+              return 0;
+            }
+        }
     }
   return -1;
 }