diff --git a/lib/tempname.c b/lib/tempname.c
index 26a38ce..5944ee0 100644
--- a/lib/tempname.c
+++ b/lib/tempname.c
@@ -20,6 +20,7 @@
 #if !_LIBC
 # include <config.h>
 # include "tempname.h"
+# include "randint.h"
 #endif

 #include <sys/types.h>
@@ -47,6 +48,7 @@
 # error report this to bug-gnulib@gnu.org
 #endif

+#include <stdbool.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
@@ -175,14 +177,21 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
 }
 #endif /* _LIBC */

+static inline bool _GL_ATTRIBUTE_PURE
+check_x_suffix (char const *s, size_t len)
+{
+  return len <= strspn (s, "X");
+}
+
 /* These are the characters used in temporary file names.  */
 static const char letters[] =
 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

 /* Generate a temporary file name based on TMPL.  TMPL must match the
-   rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
+   rules for mk[s]temp (i.e. end in at least X_SUFFIX_LEN "X"s,
+   possibly with a suffix).
    The name constructed does not exist at the time of the call to
-   __gen_tempname.  TMPL is overwritten with the result.
+   this function.  TMPL is overwritten with the result.

    KIND may be one of:
    __GT_NOCREATE:       simply verify that the name does not exist
@@ -193,23 +202,24 @@ static const char letters[] =

    We use a clever algorithm to get hard-to-predict names. */
 int
-__gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
+gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind,
+                  size_t x_suffix_len)
 {
-  int len;
+  size_t len;
   char *XXXXXX;
-  static uint64_t value;
-  uint64_t random_time_bits;
   unsigned int count;
   int fd = -1;
   int save_errno = errno;
   struct_stat64 st;
+  struct randint_source *rand_src;

   /* A lower bound on the number of temporary files to attempt to
      generate.  The maximum total number of temporary file names that
      can exist for a given template is 62**6.  It should never be
      necessary to try all of these combinations.  Instead if a reasonable
      number of names is tried (we define reasonable as 62**3) fail to
-     give the system administrator the chance to remove the problems.  */
+     give the system administrator the chance to remove the problems.
+     This value requires that X_SUFFIX_LEN be at least 3.  */
 #define ATTEMPTS_MIN (62 * 62 * 62)

   /* The number of times to attempt to generate a temporary file.  To
@@ -221,43 +231,28 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
 #endif

   len = strlen (tmpl);
-  if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen], "XXXXXX", 6))
+  if (len < x_suffix_len + suffixlen
+      || ! check_x_suffix (&tmpl[len - x_suffix_len - suffixlen],
+                           x_suffix_len))
     {
       __set_errno (EINVAL);
       return -1;
     }

   /* This is where the Xs start.  */
-  XXXXXX = &tmpl[len - 6 - suffixlen];
+  XXXXXX = &tmpl[len - x_suffix_len - suffixlen];

   /* Get some more or less random data.  */
-#ifdef RANDOM_BITS
-  RANDOM_BITS (random_time_bits);
-#else
-  {
-    struct timeval tv;
-    __gettimeofday (&tv, NULL);
-    random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
-  }
-#endif
-  value += random_time_bits ^ __getpid ();
+  rand_src = randint_all_new (NULL, x_suffix_len);
+  if (! rand_src)
+    return -1;

-  for (count = 0; count < attempts; value += 7777, ++count)
+  for (count = 0; count < attempts; ++count)
     {
-      uint64_t v = value;
-
-      /* Fill in the random bits.  */
-      XXXXXX[0] = letters[v % 62];
-      v /= 62;
-      XXXXXX[1] = letters[v % 62];
-      v /= 62;
-      XXXXXX[2] = letters[v % 62];
-      v /= 62;
-      XXXXXX[3] = letters[v % 62];
-      v /= 62;
-      XXXXXX[4] = letters[v % 62];
-      v /= 62;
-      XXXXXX[5] = letters[v % 62];
+      size_t i;
+
+      for (i = 0; i < x_suffix_len; i++)
+        XXXXXX[i] = letters[randint_genmax (rand_src, sizeof letters - 2)];

       switch (kind)
         {
@@ -272,7 +267,7 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
           break;

         case __GT_NOCREATE:
-          /* This case is backward from the other three.  __gen_tempname
+          /* This case is backward from the other three.  This function
              succeeds if __xstat fails because the name does not exist.
              Note the continue to bypass the common logic at the bottom
              of the loop.  */
@@ -281,11 +276,15 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
               if (errno == ENOENT)
                 {
                   __set_errno (save_errno);
-                  return 0;
+                  fd = 0;
+                  goto done;
                 }
               else
-                /* Give up now. */
-                return -1;
+                {
+                  /* Give up now. */
+                  fd = -1;
+                  goto done;
+                }
             }
           continue;

@@ -297,13 +296,32 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
       if (fd >= 0)
         {
           __set_errno (save_errno);
-          return fd;
+          goto done;
         }
       else if (errno != EEXIST)
-        return -1;
+        {
+          fd = -1;
+          goto done;
+        }
     }

+  randint_all_free (rand_src);
+
   /* We got out of the loop because we ran out of combinations to try.  */
   __set_errno (EEXIST);
   return -1;
+
+ done:
+  {
+    int saved_errno = errno;
+    randint_all_free (rand_src);
+    __set_errno (saved_errno);
+  }
+  return fd;
+}
+
+int
+__gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
+{
+  return gen_tempname_len (tmpl, suffixlen, flags, kind, 6);
 }
