2012-07-27 12:15:32 +02:00
|
|
|
diff --git a/lib/tempname.c b/lib/tempname.c
|
2015-04-26 15:46:18 -07:00
|
|
|
index 69c572f..1920274 100644
|
2012-07-27 12:15:32 +02:00
|
|
|
--- a/lib/tempname.c
|
|
|
|
|
+++ b/lib/tempname.c
|
|
|
|
|
@@ -20,6 +20,7 @@
|
2009-11-04 19:25:47 -07:00
|
|
|
#if !_LIBC
|
|
|
|
|
# include <config.h>
|
|
|
|
|
# include "tempname.h"
|
|
|
|
|
+# include "randint.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
2012-07-27 12:15:32 +02:00
|
|
|
@@ -47,6 +48,7 @@
|
2009-11-03 08:51:31 -07:00
|
|
|
# error report this to bug-gnulib@gnu.org
|
2009-11-04 19:25:47 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+#include <stdbool.h>
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
2015-02-11 02:09:06 +00:00
|
|
|
@@ -173,28 +175,34 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
|
2009-11-04 19:25:47 -07:00
|
|
|
}
|
|
|
|
|
#endif /* _LIBC */
|
|
|
|
|
|
maint: use "const" and "pure" function attributes where possible
* configure.ac (WARN_CFLAGS): Add -Wsuggest-attribute=const,
-Wsuggest-attribute=pure and -Wsuggest-attribute=noreturn.
(GNULIB_WARN_CFLAGS): But do not add them here... yet.
* src/chown-core.h (chopt_free, uid_to_name): Add function attribute(s).
* src/copy.c (is_ancestor, valid_options): Likewise.
* src/copy.h (chown_failure_ok): Likewise.
* src/dd.c (operand_matches, operand_is): Likewise.
* src/df.c (selected_fstype, excluded_fstype): Likewise.
* src/expr.c (null looks_like_integer): Likewise.
* src/md5sum.c (hex_digits): Likewise.
* src/od.c (get_lcm): Likewise.
* src/pathchk.c (component_start, component_len): Likewise.
* src/pinky.c (count_ampersands): Likewise.
* src/pr.c (cols_ready_to_print): Likewise.
* src/ptx.c (search_table): Likewise.
* src/sort.c (find_unit_order): Likewise.
* src/stty.c (mode_type_flag, string_to_baud, baud_to_value): Likewise.
* src/system.h (gcd, lcm): Likewise.
* src/tr.c (is_char_class_member, look_up_char_class): Likewise.
(star_digits_closebracket): Likewise.
* src/uniq.c (find_field): Likewise.
* src/wc.c (compute_number_width): Likewise.
* lib/xfts.h (cycle_warning_required): Likewise.
* gl/lib/randint.h (randint_get_source): Likewise.
* gl/lib/randperm.c (ceil_lg): Likewise.
* gl/lib/randperm.h (randperm_bound): Likewise.
* lib/strnumcmp.h (strintcmp): Likewise.
2011-04-24 19:06:39 +02:00
|
|
|
+static inline bool _GL_ATTRIBUTE_PURE
|
2009-11-04 19:25:47 -07:00
|
|
|
+check_x_suffix (char const *s, size_t len)
|
|
|
|
|
+{
|
2009-11-03 08:51:31 -07:00
|
|
|
+ return len <= strspn (s, "X");
|
2009-11-04 19:25:47 -07:00
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
/* These are the characters used in temporary file names. */
|
|
|
|
|
static const char letters[] =
|
|
|
|
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
|
|
|
|
|
|
|
|
int
|
2015-02-11 02:09:06 +00:00
|
|
|
-__try_tempname (char *tmpl, int suffixlen, void *args,
|
2015-04-26 15:46:18 -07:00
|
|
|
- int (*tryfunc) (char *, void *))
|
2015-02-11 02:09:06 +00:00
|
|
|
+try_tempname_len (char *tmpl, int suffixlen, void *args,
|
2015-04-26 15:46:18 -07:00
|
|
|
+ int (*tryfunc) (char *, void *), size_t x_suffix_len)
|
2009-11-04 19:25:47 -07:00
|
|
|
{
|
|
|
|
|
- int len;
|
|
|
|
|
+ size_t len;
|
|
|
|
|
char *XXXXXX;
|
|
|
|
|
- static uint64_t value;
|
|
|
|
|
- uint64_t random_time_bits;
|
|
|
|
|
unsigned int count;
|
|
|
|
|
int fd = -1;
|
|
|
|
|
int save_errno = errno;
|
|
|
|
|
+ struct randint_source *rand_src;
|
|
|
|
|
|
|
|
|
|
/* 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
|
2012-05-24 12:32:41 +02:00
|
|
|
necessary to try all of these combinations. Instead if a reasonable
|
2009-11-04 19:25:47 -07:00
|
|
|
number of names is tried (we define reasonable as 62**3) fail to
|
|
|
|
|
- give the system administrator the chance to remove the problems. */
|
|
|
|
|
+ give the system administrator the chance to remove the problems.
|
|
|
|
|
+ This value requires that X_SUFFIX_LEN be at least 3. */
|
|
|
|
|
#define ATTEMPTS_MIN (62 * 62 * 62)
|
|
|
|
|
|
|
|
|
|
/* The number of times to attempt to generate a temporary file. To
|
2015-02-11 02:09:06 +00:00
|
|
|
@@ -206,57 +214,55 @@ __try_tempname (char *tmpl, int suffixlen, void *args,
|
2009-11-04 19:25:47 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
len = strlen (tmpl);
|
2009-11-03 08:51:31 -07:00
|
|
|
- if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen], "XXXXXX", 6))
|
|
|
|
|
+ if (len < x_suffix_len + suffixlen
|
|
|
|
|
+ || ! check_x_suffix (&tmpl[len - x_suffix_len - suffixlen],
|
|
|
|
|
+ x_suffix_len))
|
2009-11-04 19:25:47 -07:00
|
|
|
{
|
|
|
|
|
__set_errno (EINVAL);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This is where the Xs start. */
|
2009-11-03 08:51:31 -07:00
|
|
|
- XXXXXX = &tmpl[len - 6 - suffixlen];
|
|
|
|
|
+ XXXXXX = &tmpl[len - x_suffix_len - suffixlen];
|
2009-11-04 19:25:47 -07:00
|
|
|
|
|
|
|
|
/* Get some more or less random data. */
|
|
|
|
|
-#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;
|
|
|
|
|
- }
|
|
|
|
|
-#endif
|
|
|
|
|
- value += random_time_bits ^ __getpid ();
|
2011-08-08 00:29:46 -07:00
|
|
|
+ rand_src = randint_all_new (NULL, x_suffix_len);
|
2009-11-04 19:25:47 -07:00
|
|
|
+ if (! rand_src)
|
|
|
|
|
+ return -1;
|
|
|
|
|
|
|
|
|
|
- for (count = 0; count < attempts; value += 7777, ++count)
|
|
|
|
|
+ for (count = 0; count < attempts; ++count)
|
|
|
|
|
{
|
|
|
|
|
- uint64_t v = value;
|
|
|
|
|
-
|
|
|
|
|
- /* 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];
|
|
|
|
|
+ size_t i;
|
|
|
|
|
+
|
|
|
|
|
+ for (i = 0; i < x_suffix_len; i++)
|
|
|
|
|
+ XXXXXX[i] = letters[randint_genmax (rand_src, sizeof letters - 2)];
|
|
|
|
|
|
2015-04-26 15:46:18 -07:00
|
|
|
fd = tryfunc (tmpl, args);
|
2009-11-04 19:25:47 -07:00
|
|
|
if (fd >= 0)
|
2009-12-11 19:18:04 +01:00
|
|
|
{
|
|
|
|
|
__set_errno (save_errno);
|
|
|
|
|
- return fd;
|
|
|
|
|
+ goto done;
|
|
|
|
|
}
|
2009-11-04 19:25:47 -07:00
|
|
|
else if (errno != EEXIST)
|
2009-12-11 19:18:04 +01:00
|
|
|
- return -1;
|
|
|
|
|
+ {
|
|
|
|
|
+ fd = -1;
|
|
|
|
|
+ goto done;
|
|
|
|
|
+ }
|
2009-11-04 19:25:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ randint_all_free (rand_src);
|
|
|
|
|
+
|
|
|
|
|
/* We got out of the loop because we ran out of combinations to try. */
|
|
|
|
|
__set_errno (EEXIST);
|
|
|
|
|
return -1;
|
|
|
|
|
+
|
|
|
|
|
+ done:
|
|
|
|
|
+ {
|
|
|
|
|
+ int saved_errno = errno;
|
|
|
|
|
+ randint_all_free (rand_src);
|
|
|
|
|
+ __set_errno (saved_errno);
|
|
|
|
|
+ }
|
|
|
|
|
+ return fd;
|
2015-02-11 02:09:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2015-04-26 15:46:18 -07:00
|
|
|
@@ -285,9 +291,10 @@ try_nocreate (char *tmpl, void *flags _GL_UNUSED)
|
2015-02-11 02:09:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Generate a temporary file name based on TMPL. TMPL must match the
|
|
|
|
|
- rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
|
|
|
|
|
+ rules for mk[s]temp (i.e., end in at least X_SUFFIX_LEN "X"s,
|
|
|
|
|
+ possibly with a suffix).
|
|
|
|
|
The name constructed does not exist at the time of the call to
|
|
|
|
|
- __gen_tempname. TMPL is overwritten with the result.
|
|
|
|
|
+ this function. TMPL is overwritten with the result.
|
|
|
|
|
|
|
|
|
|
KIND may be one of:
|
|
|
|
|
__GT_NOCREATE: simply verify that the name does not exist
|
2015-04-26 15:46:18 -07:00
|
|
|
@@ -298,7 +305,8 @@ try_nocreate (char *tmpl, void *flags _GL_UNUSED)
|
2015-02-11 02:09:06 +00:00
|
|
|
|
|
|
|
|
We use a clever algorithm to get hard-to-predict names. */
|
|
|
|
|
int
|
|
|
|
|
-__gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
|
|
|
|
+gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind,
|
|
|
|
|
+ size_t x_suffix_len)
|
|
|
|
|
{
|
2015-04-26 15:46:18 -07:00
|
|
|
int (*tryfunc) (char *, void *);
|
2015-02-11 02:09:06 +00:00
|
|
|
|
|
|
|
|
@@ -320,5 +328,18 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
|
|
|
|
assert (! "invalid KIND in __gen_tempname");
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
2015-04-26 15:46:18 -07:00
|
|
|
- return __try_tempname (tmpl, suffixlen, &flags, tryfunc);
|
|
|
|
|
+ return try_tempname_len (tmpl, suffixlen, &flags, tryfunc, x_suffix_len);
|
2009-11-04 19:25:47 -07:00
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int
|
2009-11-03 08:51:31 -07:00
|
|
|
+__gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
2009-11-04 19:25:47 -07:00
|
|
|
+{
|
2009-11-03 08:51:31 -07:00
|
|
|
+ return gen_tempname_len (tmpl, suffixlen, flags, kind, 6);
|
2015-02-11 02:09:06 +00:00
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+int
|
|
|
|
|
+__try_tempname (char *tmpl, int suffixlen, void *args,
|
2015-04-26 15:46:18 -07:00
|
|
|
+ int (*tryfunc) (char *, void *))
|
2015-02-11 02:09:06 +00:00
|
|
|
+{
|
2015-04-26 15:46:18 -07:00
|
|
|
+ return try_tempname_len (tmpl, suffixlen, args, tryfunc, 6);
|
2009-11-04 19:25:47 -07:00
|
|
|
}
|