summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/features.h13
-rw-r--r--libc/misc/internals/tempname.c106
-rw-r--r--libc/stdio/tempnam.c7
-rw-r--r--libc/stdio/tmpfile.c6
-rw-r--r--libc/stdio/tmpnam.c10
-rw-r--r--libc/stdio/tmpnam_r.c6
-rw-r--r--libc/stdlib/Makefile4
-rw-r--r--libc/stdlib/mkstemp.c4
-rw-r--r--libc/stdlib/mkstemp64.c29
-rw-r--r--libc/stdlib/mktemp.c4
10 files changed, 116 insertions, 73 deletions
diff --git a/include/features.h b/include/features.h
index 98e575dca..e1060ce3e 100644
--- a/include/features.h
+++ b/include/features.h
@@ -417,6 +417,19 @@ uClibc was built without large file support enabled.
/* --- this is added to integrate linuxthreads */
#define __USE_UNIX98 1
+/* For want of a better place, here are some function prototypes
+ * for things from libc/misc/internals */
+#define __need_size_t
+#include <stddef.h>
+extern int __path_search (char *tmpl, size_t tmpl_len, const char *dir,
+ const char *pfx, int try_tmpdir);
+extern int __gen_tempname (char *__tmpl, int __kind);
+/* The __kind argument to __gen_tempname may be one of: */
+#define __GT_FILE 0 /* create a file */
+#define __GT_BIGFILE 1 /* create a file, using open64 */
+#define __GT_DIR 2 /* create a directory */
+#define __GT_NOCREATE 3 /* just find a name not currently in use */
+
#endif /* _LIBC only stuff */
diff --git a/libc/misc/internals/tempname.c b/libc/misc/internals/tempname.c
index 41325d998..427c16cb5 100644
--- a/libc/misc/internals/tempname.c
+++ b/libc/misc/internals/tempname.c
@@ -27,12 +27,14 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/time.h>
+
/* Return nonzero if DIR is an existent directory. */
static int direxists (const char *dir)
{
@@ -46,8 +48,8 @@ static int direxists (const char *dir)
for use with mk[s]temp. Will fail (-1) if DIR is non-null and
doesn't exist, none of the searched dirs exists, or there's not
enough space in TMPL. */
-int __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
- int try_tmpdir)
+int __path_search (char *tmpl, size_t tmpl_len, const char *dir,
+ const char *pfx, int try_tmpdir)
{
//const char *d;
size_t dlen, plen;
@@ -111,22 +113,28 @@ static const char letters[] =
/* Generate a temporary file name based on TMPL. TMPL must match the
rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
does not exist at the time of the call to __gen_tempname. TMPL is
- overwritten with the result. If OPENIT is nonzero, creates the
- file and returns a read-write fd; the file is mode 0600 modulo
- umask. If LARGEFILE is nonzero, uses open64() instead of open().
+ overwritten with the result.
+
+ KIND may be one of:
+ __GT_NOCREATE: simply verify that the name does not exist
+ at the time of the call.
+ __GT_FILE: create the file using open(O_CREAT|O_EXCL)
+ and return a read-write fd. The file is mode 0600.
+ __GT_BIGFILE: same as __GT_FILE but use open64().
+ __GT_DIR: create a directory, which will be mode 0700.
We use a clever algorithm to get hard-to-predict names. */
-int __gen_tempname (char *tmpl, int openit)
+int __gen_tempname (char *tmpl, int kind)
{
int len;
char *XXXXXX;
static uint64_t value;
struct timeval tv;
- uint32_t high, low, rh;
- unsigned int k;
+ uint32_t high, low, rh;
+ unsigned int k;
int count, fd;
int save_errno = errno;
- int i;
+ int i;
len = strlen (tmpl);
if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
@@ -148,46 +156,60 @@ int __gen_tempname (char *tmpl, int openit)
high = value >> 32;
for (i = 0 ; i < 6 ; i++) {
- rh = high % 62;
- high /= 62;
+ rh = high % 62;
+ high /= 62;
#define L ((UINT32_MAX % 62 + 1) % 62)
- k = (low % 62) + (L * rh);
+ k = (low % 62) + (L * rh);
#undef L
#define H ((UINT32_MAX / 62) + ((UINT32_MAX % 62 + 1) / 62))
- low = (low / 62) + (H * rh) + (k / 62);
+ low = (low / 62) + (H * rh) + (k / 62);
#undef H
- k %= 62;
- XXXXXX[i] = letters[k];
+ k %= 62;
+ XXXXXX[i] = letters[k];
}
- if (openit)
- {
- fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, 0600);
- if (fd >= 0)
- {
- __set_errno (save_errno);
- return fd;
- }
- else if (errno != EEXIST)
- /* Any other error will apply also to other names we might
- try, and there are 2^32 or so of them, so give up now. */
- return -1;
- }
- else
- {
- struct stat st;
- if (stat (tmpl, &st) < 0)
- {
- if (errno == ENOENT)
+ switch(kind) {
+ case __GT_NOCREATE:
{
- __set_errno (save_errno);
- return 0;
+ struct stat st;
+ if (stat (tmpl, &st) < 0)
+ {
+ if (errno == ENOENT)
+ {
+ __set_errno (save_errno);
+ return 0;
+ }
+ else
+ /* Give up now. */
+ return -1;
+ }
+ else
+ continue;
}
- else
- /* Give up now. */
- return -1;
- }
+ case __GT_FILE:
+ fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ break;
+#if defined __UCLIBC_HAVE_LFS__
+ case __GT_BIGFILE:
+ fd = open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ break;
+#endif
+ case __GT_DIR:
+ fd = mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
+ break;
+ default:
+ fd = -1;
+ assert (! "invalid KIND in __gen_tempname");
}
+
+ if (fd >= 0) {
+ __set_errno (save_errno);
+ return fd;
+ }
+ else if (errno != EEXIST)
+ /* Any other error will apply also to other names we might
+ try, and there are 2^32 or so of them, so give up now. */
+ return -1;
}
/* We got out of the loop because we ran out of combinations to try. */
diff --git a/libc/stdio/tempnam.c b/libc/stdio/tempnam.c
index 4beb5af83..109276de7 100644
--- a/libc/stdio/tempnam.c
+++ b/libc/stdio/tempnam.c
@@ -19,11 +19,6 @@
#include <stdio.h>
#include <string.h>
-extern int __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
- int try_tmpdir);
-extern int __gen_tempname (char *tmpl, int openit);
-
-
/* Generate a unique temporary filename using up to five characters of PFX
if it is not NULL. The directory to put this file in is searched for
as follows: First the environment variable "TMPDIR" is checked.
@@ -39,7 +34,7 @@ tempnam (const char *dir, const char *pfx)
if (__path_search (buf, FILENAME_MAX, dir, pfx, 1))
return NULL;
- if (__gen_tempname (buf, 0))
+ if (__gen_tempname (buf, __GT_NOCREATE))
return NULL;
return strdup (buf);
diff --git a/libc/stdio/tmpfile.c b/libc/stdio/tmpfile.c
index 7669e46db..f19c497a4 100644
--- a/libc/stdio/tmpfile.c
+++ b/libc/stdio/tmpfile.c
@@ -20,10 +20,6 @@
#include <stdio.h>
#include <unistd.h>
-extern int __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
- int try_tmpdir);
-extern int __gen_tempname (char *tmpl, int openit);
-
/* This returns a new stream opened on a temporary file (generated
by tmpnam). The file is opened with mode "w+b" (binary read/write).
If we couldn't generate a unique filename or the file couldn't
@@ -36,7 +32,7 @@ FILE * tmpfile (void)
if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
return NULL;
- fd = __gen_tempname (buf, 1);
+ fd = __gen_tempname (buf, __GT_FILE);
if (fd < 0)
return NULL;
diff --git a/libc/stdio/tmpnam.c b/libc/stdio/tmpnam.c
index 296f67f27..23cba46ed 100644
--- a/libc/stdio/tmpnam.c
+++ b/libc/stdio/tmpnam.c
@@ -19,15 +19,11 @@
#include <stdio.h>
#include <string.h>
-extern int __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
- int try_tmpdir);
-extern int __gen_tempname (char *tmpl, int openit);
-
static char tmpnam_buffer[L_tmpnam];
/* Generate a unique filename in P_tmpdir.
-
- This function is *not* thread safe when S == NULL! */
+ This function is *not* thread safe when S == NULL!
+*/
char * tmpnam (char *s)
{
/* By using two buffers we manage to be thread safe in the case
@@ -40,7 +36,7 @@ char * tmpnam (char *s)
if (__path_search (s ? : tmpbuf, L_tmpnam, NULL, NULL, 0))
return NULL;
- if (__gen_tempname (s ? : tmpbuf, 0))
+ if (__gen_tempname (s ? : tmpbuf, __GT_NOCREATE))
return NULL;
if (s == NULL)
diff --git a/libc/stdio/tmpnam_r.c b/libc/stdio/tmpnam_r.c
index 630d96eb3..6309aac06 100644
--- a/libc/stdio/tmpnam_r.c
+++ b/libc/stdio/tmpnam_r.c
@@ -18,10 +18,6 @@
#include <stdio.h>
-extern int __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
- int try_tmpdir);
-extern int __gen_tempname (char *tmpl, int openit);
-
/* Generate a unique filename in P_tmpdir. If S is NULL return NULL.
This makes this function thread safe. */
char * tmpnam_r (char *s)
@@ -31,7 +27,7 @@ char * tmpnam_r (char *s)
if (__path_search (s, L_tmpnam, NULL, NULL, 0))
return NULL;
- if (__gen_tempname (s, 0))
+ if (__gen_tempname (s, __GT_NOCREATE))
return NULL;
return s;
diff --git a/libc/stdlib/Makefile b/libc/stdlib/Makefile
index 71136c2fa..44a359434 100644
--- a/libc/stdlib/Makefile
+++ b/libc/stdlib/Makefile
@@ -38,8 +38,8 @@ MSRC2=atexit.c
MOBJ2=atexit.o on_exit.o __exit_handler.o exit.o
CSRC = abort.c getenv.c mktemp.c qsort.c realpath.c bsearch.c \
- mkstemp.c putenv.c rand.c random.c random_r.c setenv.c system.c div.c \
- ldiv.c getpt.c ptsname.c grantpt.c unlockpt.c gcvt.c
+ mkstemp.c mkstemp64.c putenv.c rand.c random.c random_r.c setenv.c \
+ system.c div.c ldiv.c getpt.c ptsname.c grantpt.c unlockpt.c gcvt.c
CSRC+= drand48.c drand48-iter.c drand48_r.c erand48.c erand48_r.c \
jrand48.c jrand48_r.c lrand48.c lrand48_r.c mrand48.c mrand48_r.c \
nrand48.c nrand48_r.c rand_r.c srand48.c srand48_r.c
diff --git a/libc/stdlib/mkstemp.c b/libc/stdlib/mkstemp.c
index d0104c8f3..de5d557f4 100644
--- a/libc/stdlib/mkstemp.c
+++ b/libc/stdlib/mkstemp.c
@@ -19,13 +19,11 @@
#include <stdio.h>
#include <stdlib.h>
-extern int __gen_tempname (char *tmpl, int openit);
-
/* Generate a unique temporary file name from TEMPLATE.
The last six characters of TEMPLATE must be "XXXXXX";
they are replaced with a string that makes the filename unique.
Then open the file and return a fd. */
int mkstemp (char *template)
{
- return __gen_tempname (template, 1);
+ return __gen_tempname (template, __GT_FILE);
}
diff --git a/libc/stdlib/mkstemp64.c b/libc/stdlib/mkstemp64.c
new file mode 100644
index 000000000..5762da79d
--- /dev/null
+++ b/libc/stdlib/mkstemp64.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1998 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
+ 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.
+
+ 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.
+
+ 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. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Generate a unique temporary file name from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the filename unique.
+ Then open the file and return a fd. */
+int mkstemp64 (char *template)
+{
+ return __gen_tempname (template, __GT_BIGFILE);
+}
diff --git a/libc/stdlib/mktemp.c b/libc/stdlib/mktemp.c
index 432d64f2a..4faa3e671 100644
--- a/libc/stdlib/mktemp.c
+++ b/libc/stdlib/mktemp.c
@@ -19,14 +19,12 @@
#include <stdio.h>
#include <stdlib.h>
-extern int __gen_tempname (char *tmpl, int openit);
-
/* Generate a unique temporary file name from TEMPLATE.
The last six characters of TEMPLATE must be "XXXXXX";
they are replaced with a string that makes the filename unique. */
char * mktemp (char *template)
{
- if (__gen_tempname (template, 0) < 0)
+ if (__gen_tempname (template, __GT_NOCREATE) < 0)
/* We return the null string if we can't find a unique file name. */
template[0] = '\0';