From 512e44adaebb3096ddd1bf564e679d06e0301616 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 16 Aug 2022 12:06:48 -0700 Subject: [PATCH] tempname: generate better names for MinGW Emacs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 | 14 ++++++++++++++ lib/tempname.c | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b639d1709d..eb96281591 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2022-08-16 Paul Eggert + + 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 Simon Josefsson maintainer-makefile: Check for incorrect DISTCHECK_CONFIGURE_FLAGS diff --git a/lib/tempname.c b/lib/tempname.c index e6520191d7..5adfe629a8 100644 --- a/lib/tempname.c +++ b/lib/tempname.c @@ -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 . */ + 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) -- 2.34.1