X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Ftempname.c;h=e213600e3f2b33ea851e1d2bc418cb9646ce1bf4;hb=9fbb5dcb459bf25d5e7b89fc209359e1a61a5214;hp=0c9853e3b606b8c842e2f201ab857a56ff4208ea;hpb=85169d2512798847e7c3483ebf13dd34f113946b;p=gnulib.git diff --git a/lib/tempname.c b/lib/tempname.c index 0c9853e3b..e213600e3 100644 --- a/lib/tempname.c +++ b/lib/tempname.c @@ -1,23 +1,28 @@ -/* Copyright (C) 1991-1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* tempname.c - generate the name of a temporary file. - 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. + Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2005, 2006, 2007 Free Software Foundation, + Inc. - The GNU C Library is distributed in the hope that it will be useful, + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - 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. */ +/* Extracted from glibc sysdeps/posix/tempname.c. See also tmpdir.c. */ -#if HAVE_CONFIG_H +#if !_LIBC # include +# include "tempname.h" #endif #include @@ -42,75 +47,53 @@ # define __GT_NOCREATE 3 #endif -#if STDC_HEADERS || _LIBC -# include -# include -# include -#endif +#include +#include +#include -#if HAVE_FCNTL_H || _LIBC -# include -#endif - -#if HAVE_SYS_TIME_H || _LIBC -# include -#endif - -#if HAVE_STDINT_H || _LIBC -# include -#endif - -#if HAVE_UNISTD_H || _LIBC -# include -#endif +#include +#include +#include +#include #include -#if STAT_MACROS_BROKEN -# undef S_ISDIR -#endif -#if !defined S_ISDIR && defined S_IFDIR -# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -#endif -#if !S_IRUSR && S_IREAD -# define S_IRUSR S_IREAD -#endif -#if !S_IRUSR -# define S_IRUSR 00400 -#endif -#if !S_IWUSR && S_IWRITE -# define S_IWUSR S_IWRITE -#endif -#if !S_IWUSR -# define S_IWUSR 00200 -#endif -#if !S_IXUSR && S_IEXEC -# define S_IXUSR S_IEXEC -#endif -#if !S_IXUSR -# define S_IXUSR 00100 -#endif #if _LIBC # define struct_stat64 struct stat64 +# define small_open __open +# define large_open __open64 #else # define struct_stat64 struct stat +# define small_open open +# define large_open open +# define __gen_tempname gen_tempname # define __getpid getpid # define __gettimeofday gettimeofday # define __mkdir mkdir -# define __open open -# define __open64 open -# define __lxstat64(version, path, buf) lstat (path, buf) -# define __xstat64(version, path, buf) stat (path, buf) +# define __lxstat64(version, file, buf) lstat (file, buf) +# define __xstat64(version, file, buf) stat (file, buf) #endif #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 @@ -123,6 +106,7 @@ char *getenv (); # define uint64_t uintmax_t #endif +#if _LIBC /* Return nonzero if DIR is an existent directory. */ static int direxists (const char *dir) @@ -193,8 +177,9 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx); return 0; } +#endif /* _LIBC */ -/* These are the characters used in temporary filenames. */ +/* These are the characters used in temporary file names. */ static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; @@ -219,10 +204,27 @@ __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. */ +#define 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. */ +#if ATTEMPTS_MIN < TMP_MAX + unsigned int attempts = TMP_MAX; +#else + unsigned int attempts = ATTEMPTS_MIN; +#endif + len = strlen (tmpl); if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX")) { @@ -234,18 +236,18 @@ __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 { struct timeval tv; __gettimeofday (&tv, NULL); random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; } -#else - random_time_bits = time (NULL); #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; @@ -265,11 +267,11 @@ __gen_tempname (char *tmpl, int kind) switch (kind) { case __GT_FILE: - fd = __open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + fd = small_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); break; case __GT_BIGFILE: - fd = __open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + fd = large_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); break; case __GT_DIR: