about summary refs log tree commit diff
path: root/sysdeps/posix/tempname.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/posix/tempname.c')
-rw-r--r--sysdeps/posix/tempname.c90
1 files changed, 35 insertions, 55 deletions
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index 291817c9ef..82e0243132 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+/* Copyright (C) 1991,92,93,94,95,96,97,98 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -16,15 +16,17 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <errno.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <sys/time.h>
 
 #ifdef USE_IN_LIBIO
 # include "libioP.h"
@@ -87,14 +89,11 @@ __stdio_gen_tempname (char *buf, size_t bufsize, const char *dir,
 {
   int saverrno = errno;
   static const char tmpdir[] = P_tmpdir;
-  static size_t indices[2];
-  size_t *idx;
-#if 0
-  static pid_t oldpid = (pid_t) 0;
-#endif
-  pid_t pid = __getpid();
-  register size_t len, plen, dlen;
-  int wrapped;
+  size_t plen, dlen, len;
+  char *XXXXXX;
+  static uint64_t value;
+  struct timeval tv;
+  int count;
 
   if (dir_search)
     {
@@ -132,56 +131,37 @@ __stdio_gen_tempname (char *buf, size_t bufsize, const char *dir,
   else
     plen = 0;
 
-  if (dir != tmpdir && !strcmp (dir, tmpdir))
-    dir = tmpdir;
-  idx = &indices[(plen == 0 && dir == tmpdir) ? 1 : 0];
-
-#if 0
-  /* XXX Is this ever useful???  At least when using a thread package
-     which uses different PIDs for the threads it is not helpful.  */
-  if (pid != oldpid)
-    {
-      oldpid = pid;
-      indices[0] = indices[1] = 0;
-    }
-#endif
-
-  wrapped = 0; /* We have not yet wrapped around the index counter.  */
-  len = dlen + 1 + plen + 5 + 3;
-  while (1)
-    {
-      size_t i;
+  len = __snprintf (buf, bufsize, "%.*s/%.*sXXXXXX",
+	      (int) dlen, dir, (int) plen, pfx);
 
-      if (*idx >= ((sizeof (letters) - 1) * (sizeof (letters) - 1) *
-		   (sizeof (letters) - 1)))
-	{
-	  if (wrapped)
-	    /* We really wrapped around this call.  Can't believe it
-	       but nevertheless stop the endless loop.  */
-	    break;
+  if (len < dlen + plen + 7)
+  {
+      __set_errno (EINVAL);
+      return NULL;
+  }
 
-	  indices[0] = indices[1] = 0;
-	  wrapped = 1;
-	}
-
-      i = (*idx)++;
+  XXXXXX = &buf[dlen + plen + 1];
 
-      /* Construct a file name and see if it already exists.
+  /* Get some more or less random data.  */
+  __gettimeofday (&tv, NULL);
+  value += ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ __getpid ();
 
-	 We use a single counter in *IDX to cycle each of three
-	 character positions through each of 62 possible letters.  */
+  for (count = 0; count < TMP_MAX; value += 7777, ++count)
+    {
+      uint64_t v = value;
 
-      if (__snprintf (buf, bufsize, "%.*s/%.*s%.5d%c%c%c",
-		      (int) dlen, dir, (int) plen,
-		      pfx, pid % 100000,
-		      letters[i % (sizeof (letters) - 1)],
-		      letters[(i / (sizeof (letters) - 1))
-			     % (sizeof (letters) - 1)],
-		      letters[(i / ((sizeof (letters) - 1) *
-				    (sizeof (letters) - 1)))
-			     % (sizeof (letters) - 1)]
-		    ) != (int) len)
-	return NULL;
+      /* 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];
 
       if (streamptr != NULL)
 	{