aboutsummaryrefslogtreecommitdiff
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 291817c..82e0243 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)
{