]> Savannah Git Hosting - gnulib.git/commitdiff
tempname: generate better names for MinGW Emacs
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 16 Aug 2022 19:06:48 +0000 (12:06 -0700)
committerBruno Haible <bruno@clisp.org>
Wed, 31 Aug 2022 23:28:16 +0000 (01:28 +0200)
On MinGW, GNU Emacs disables clock_gettime, which reliably breaks
some of gen_tempname’s optimistic callers.  Work around the
problem by making the generated names less predictable.  We don’t
need cryptographic randomness here, just enough unpredictability
to keep Emacs happy most of the time.
* lib/tempname.c (HAS_CLOCK_ENTROPY): New macro.
(random_bits): Use it.
(try_tempname_len): On systems lacking clock entropy, maintain
state so that gen_filename generates less-predictable names on
successive successful calls.

ChangeLog
lib/tempname.c

index 56ba2a6955dda8c466991df0b759f6a0e97634ab..bb52632cd25d30547ff92524e0561c09b869a9d9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2022-08-16  Paul Eggert  <eggert@cs.ucla.edu>
+
+       tempname: generate better names for MinGW Emacs
+       On MinGW, GNU Emacs disables clock_gettime, which reliably breaks
+       some of gen_tempname’s optimistic callers.  Work around the
+       problem by making the generated names less predictable.  We don’t
+       need cryptographic randomness here, just enough unpredictability
+       to keep Emacs happy most of the time.
+       * lib/tempname.c (HAS_CLOCK_ENTROPY): New macro.
+       (random_bits): Use it.
+       (try_tempname_len): On systems lacking clock entropy, maintain
+       state so that gen_filename generates less-predictable names on
+       successive successful calls.
+
 2022-08-16  Bruno Haible  <bruno@clisp.org>
 
        tempname: Add tests.
index e6520191d7ebe0f607b54e7c83e4f54bd1f8c547..5adfe629a88248694c7ca832e8a5fdb328a148e2 100644 (file)
@@ -77,6 +77,12 @@ typedef uint_fast64_t random_value;
 #define BASE_62_DIGITS 10 /* 62**10 < UINT_FAST64_MAX */
 #define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62)
 
+#if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME)
+# define HAS_CLOCK_ENTROPY true
+#else
+# define HAS_CLOCK_ENTROPY false
+#endif
+
 static random_value
 random_bits (random_value var, bool use_getrandom)
 {
@@ -84,7 +90,7 @@ random_bits (random_value var, bool use_getrandom)
   /* Without GRND_NONBLOCK it can be blocked for minutes on some systems.  */
   if (use_getrandom && __getrandom (&r, sizeof r, GRND_NONBLOCK) == sizeof r)
     return r;
-#if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME)
+#if HAS_CLOCK_ENTROPY
   /* Add entropy if getrandom did not work.  */
   struct __timespec64 tv;
   __clock_gettime64 (CLOCK_MONOTONIC, &tv);
@@ -267,6 +273,13 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
      alignment.  */
   random_value v = ((uintptr_t) &v) / alignof (max_align_t);
 
+#if !HAS_CLOCK_ENTROPY
+  /* Arrange gen_tempname to return less predictable file names on
+     systems lacking clock entropy <https://bugs.gnu.org/57129>.  */
+  static random_value prev_v;
+  v ^= prev_v;
+#endif
+
   /* How many random base-62 digits can currently be extracted from V.  */
   int vdigits = 0;
 
@@ -318,6 +331,9 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
       if (fd >= 0)
         {
           __set_errno (save_errno);
+#if !HAS_CLOCK_ENTROPY
+          prev_v = v;
+#endif
           return fd;
         }
       else if (errno != EEXIST)