+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.
#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)
{
/* 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);
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;
if (fd >= 0)
{
__set_errno (save_errno);
+#if !HAS_CLOCK_ENTROPY
+ prev_v = v;
+#endif
return fd;
}
else if (errno != EEXIST)