X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Ftempname.c;h=bf5a15d04415484f94840d9735e34727d4c2e490;hb=4b4109233097408185555b472eb302c8d3da33b9;hp=0c9853e3b606b8c842e2f201ab857a56ff4208ea;hpb=85169d2512798847e7c3483ebf13dd34f113946b;p=gnulib.git diff --git a/lib/tempname.c b/lib/tempname.c index 0c9853e3b..bf5a15d04 100644 --- a/lib/tempname.c +++ b/lib/tempname.c @@ -2,19 +2,19 @@ This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #if HAVE_CONFIG_H # include @@ -44,10 +44,11 @@ #if STDC_HEADERS || _LIBC # include -# include # include #endif +#include + #if HAVE_FCNTL_H || _LIBC # include #endif @@ -105,12 +106,24 @@ #if ! (HAVE___SECURE_GETENV || _LIBC) # define __secure_getenv getenv +#endif -# ifndef HAVE_DECL_GETENV -"this configure-time declaration test was not run" -# endif -# if !HAVE_DECL_GETENV -char *getenv (); +#ifdef _LIBC +# include +# if HP_TIMING_AVAIL +# define RANDOM_BITS(Var) \ + if (__builtin_expect (value == UINT64_C (0), 0)) \ + { \ + /* If this is the first time this function is used initialize \ + the variable we accumulate the value in to some somewhat \ + random value. If we'd not do this programs at startup time \ + might have a reduced set of possible names, at least on slow \ + machines. */ \ + struct timeval tv; \ + __gettimeofday (&tv, NULL); \ + value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \ + } \ + HP_TIMING_NOW (Var) # endif #endif @@ -219,10 +232,23 @@ __gen_tempname (char *tmpl, int kind) char *XXXXXX; static uint64_t value; uint64_t random_time_bits; - int count, fd = -1; + unsigned int count; + int fd = -1; int save_errno = errno; struct_stat64 st; + /* 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 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. */ + unsigned int attempts_min = 62 * 62 * 62; + + /* The number of times to attempt to generate a temporary file. To + conform to POSIX, this must be no smaller than TMP_MAX. */ + unsigned int attempts = attempts_min < TMP_MAX ? TMP_MAX : attempts_min; + len = strlen (tmpl); if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX")) { @@ -234,18 +260,22 @@ __gen_tempname (char *tmpl, int kind) XXXXXX = &tmpl[len - 6]; /* Get some more or less random data. */ -#if HAVE_GETTIMEOFDAY || _LIBC +#ifdef RANDOM_BITS + RANDOM_BITS (random_time_bits); +#else +# if HAVE_GETTIMEOFDAY || _LIBC { struct timeval tv; __gettimeofday (&tv, NULL); random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; } -#else +# else random_time_bits = time (NULL); +# endif #endif value += random_time_bits ^ __getpid (); - for (count = 0; count < TMP_MAX; value += 7777, ++count) + for (count = 0; count < attempts; value += 7777, ++count) { uint64_t v = value;