about summary refs log tree commit diff
path: root/sysdeps/posix/mkstemp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/posix/mkstemp.c')
-rw-r--r--sysdeps/posix/mkstemp.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/sysdeps/posix/mkstemp.c b/sysdeps/posix/mkstemp.c
index 3765488f73..fceb59b4be 100644
--- a/sysdeps/posix/mkstemp.c
+++ b/sysdeps/posix/mkstemp.c
@@ -19,9 +19,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <sys/time.h>
 
 /* Generate a unique temporary file name from TEMPLATE.
    The last six characters of TEMPLATE must be "XXXXXX";
@@ -33,30 +35,54 @@ mkstemp (template)
 {
   static const char letters[]
     = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+  static uint32_t value;
+  struct timeval tv;
+  char *XXXXXX;
   size_t len;
-  size_t i;
+  int count;
 
   len = strlen (template);
   if (len < 6 || strcmp (&template[len - 6], "XXXXXX"))
     {
       __set_errno (EINVAL);
-      return -1;
+      return NULL;
     }
 
-  if (sprintf (&template[len - 5], "%.5u",
-	       (unsigned int) getpid () % 100000) != 5)
-    /* Inconceivable lossage.  */
-    return -1;
+  /* This is where the Xs start.  */
+  XXXXXX = &template[len - 6];
 
-  for (i = 0; i < sizeof (letters); ++i)
+  /* Get some more or less random data.  */
+  __gettimeofday (&tv, NULL);
+  value += tv.tv_usec | getpid ();
+
+  for (count = 0; count < TMP_MAX; ++count)
     {
+      struct stat ignored;
+      uint32_t v = value;
       int fd;
 
-      template[len - 6] = letters[i];
+      /* 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];
 
       fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600);
       if (fd >= 0)
+	/* The file does not exist.  */
 	return fd;
+
+      /* This is a random value.  It is only necessary that the next
+	 TMP_MAX values generated by adding 7777 to VALUE are different
+	 with (module 2^32).  */
+      value += 7777;
     }
 
   /* We return the null string if we can't find a unique file name.  */