Browse Source

Rework __gen_tempname() to better match glibc, and add mkstemp64(),
which is needed for busybox ash when using largefile support.
-Erik

Eric Andersen 23 years ago
parent
commit
cdb29e3ea6

+ 13 - 0
include/features.h

@@ -417,6 +417,19 @@ uClibc was built without large file support enabled.
 /* --- this is added to integrate linuxthreads */
 /* --- this is added to integrate linuxthreads */
 #define __USE_UNIX98            1
 #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 */
 #endif /* _LIBC only stuff */
 
 
 
 

+ 64 - 42
libc/misc/internals/tempname.c

@@ -27,12 +27,14 @@
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
 #include <errno.h>
 #include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <fcntl.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <unistd.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/time.h>
 
 
+
 /* Return nonzero if DIR is an existent directory.  */
 /* Return nonzero if DIR is an existent directory.  */
 static int direxists (const char *dir)
 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
    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
    doesn't exist, none of the searched dirs exists, or there's not
    enough space in TMPL. */
    enough space in TMPL. */
-int __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
+int __path_search (char *tmpl, size_t tmpl_len, const char *dir, 
-	       int try_tmpdir)
+	const char *pfx, int try_tmpdir)
 {
 {
     //const char *d;
     //const char *d;
     size_t dlen, plen;
     size_t dlen, plen;
@@ -111,22 +113,28 @@ static const char letters[] =
 /* Generate a temporary file name based on TMPL.  TMPL must match the
 /* 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
    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
    does not exist at the time of the call to __gen_tempname.  TMPL is
-   overwritten with the result.  If OPENIT is nonzero, creates the
+   overwritten with the result.  
-   file and returns a read-write fd; the file is mode 0600 modulo
+
-   umask.  If LARGEFILE is nonzero, uses open64() instead of open().
+   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. */
    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;
     int len;
     char *XXXXXX;
     char *XXXXXX;
     static uint64_t value;
     static uint64_t value;
     struct timeval tv;
     struct timeval tv;
-	uint32_t high, low, rh;
+    uint32_t high, low, rh;
-	unsigned int k;
+    unsigned int k;
     int count, fd;
     int count, fd;
     int save_errno = errno;
     int save_errno = errno;
-	int i;
+    int i;
 
 
     len = strlen (tmpl);
     len = strlen (tmpl);
     if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
     if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
@@ -148,46 +156,60 @@ int __gen_tempname (char *tmpl, int openit)
 	high = value >> 32;
 	high = value >> 32;
 
 
 	for (i = 0 ; i < 6 ; i++) {
 	for (i = 0 ; i < 6 ; i++) {
-		rh = high % 62;
+	    rh = high % 62;
-		high /= 62;
+	    high /= 62;
 #define L ((UINT32_MAX % 62 + 1) % 62)
 #define L ((UINT32_MAX % 62 + 1) % 62)
-		k = (low % 62) + (L * rh);
+	    k = (low % 62) + (L * rh);
 #undef L
 #undef L
 #define H ((UINT32_MAX / 62) + ((UINT32_MAX % 62 + 1) / 62))
 #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
 #undef H
-		k %= 62;
+	    k %= 62;
-		XXXXXX[i] = letters[k];
+	    XXXXXX[i] = letters[k];
 	}
 	}
 
 
-	if (openit)
+	switch(kind) {
-	{
+	    case __GT_NOCREATE:
-	    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)
 		{
 		{
-		    __set_errno (save_errno);
+		    struct stat st;
-		    return 0;
+		    if (stat (tmpl, &st) < 0)
+		    {
+			if (errno == ENOENT)
+			{
+			    __set_errno (save_errno);
+			    return 0;
+			}
+			else
+			    /* Give up now. */
+			    return -1;
+		    }
+		    else
+			continue;
 		}
 		}
-		else
+	    case __GT_FILE:
-		    /* Give up now. */
+		fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
-		    return -1;
+		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.  */
     /* We got out of the loop because we ran out of combinations to try.  */

+ 1 - 6
libc/stdio/tempnam.c

@@ -19,11 +19,6 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <string.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
 /* 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
    if it is not NULL.  The directory to put this file in is searched for
    as follows: First the environment variable "TMPDIR" is checked.
    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))
   if (__path_search (buf, FILENAME_MAX, dir, pfx, 1))
     return NULL;
     return NULL;
 
 
-  if (__gen_tempname (buf, 0))
+  if (__gen_tempname (buf, __GT_NOCREATE))
     return NULL;
     return NULL;
 
 
   return strdup (buf);
   return strdup (buf);

+ 1 - 5
libc/stdio/tmpfile.c

@@ -20,10 +20,6 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <unistd.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
 /* This returns a new stream opened on a temporary file (generated
    by tmpnam).  The file is opened with mode "w+b" (binary read/write).
    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
    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))
     if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
 	return NULL;
 	return NULL;
-    fd = __gen_tempname (buf, 1);
+    fd = __gen_tempname (buf, __GT_FILE);
     if (fd < 0)
     if (fd < 0)
 	return NULL;
 	return NULL;
 
 

+ 3 - 7
libc/stdio/tmpnam.c

@@ -19,15 +19,11 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <string.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];
 static char tmpnam_buffer[L_tmpnam];
 
 
 /* Generate a unique filename in P_tmpdir.
 /* 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)
 char * tmpnam (char *s)
 {
 {
     /* By using two buffers we manage to be thread safe in the case
     /* 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))
     if (__path_search (s ? : tmpbuf, L_tmpnam, NULL, NULL, 0))
 	return NULL;
 	return NULL;
 
 
-    if (__gen_tempname (s ? : tmpbuf, 0))
+    if (__gen_tempname (s ? : tmpbuf, __GT_NOCREATE))
 	return NULL;
 	return NULL;
 
 
     if (s == NULL)
     if (s == NULL)

+ 1 - 5
libc/stdio/tmpnam_r.c

@@ -18,10 +18,6 @@
 
 
 #include <stdio.h>
 #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.
 /* Generate a unique filename in P_tmpdir.  If S is NULL return NULL.
    This makes this function thread safe.  */
    This makes this function thread safe.  */
 char * tmpnam_r (char *s)
 char * tmpnam_r (char *s)
@@ -31,7 +27,7 @@ char * tmpnam_r (char *s)
 
 
     if (__path_search (s, L_tmpnam, NULL, NULL, 0))
     if (__path_search (s, L_tmpnam, NULL, NULL, 0))
 	return NULL;
 	return NULL;
-    if (__gen_tempname (s, 0))
+    if (__gen_tempname (s, __GT_NOCREATE))
 	return NULL;
 	return NULL;
 
 
     return s;
     return s;

+ 2 - 2
libc/stdlib/Makefile

@@ -38,8 +38,8 @@ MSRC2=atexit.c
 MOBJ2=atexit.o on_exit.o __exit_handler.o exit.o
 MOBJ2=atexit.o on_exit.o __exit_handler.o exit.o
 
 
 CSRC =	abort.c getenv.c mktemp.c qsort.c realpath.c bsearch.c \
 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 \
+	mkstemp.c mkstemp64.c putenv.c rand.c random.c random_r.c setenv.c \
-	ldiv.c getpt.c ptsname.c grantpt.c unlockpt.c gcvt.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 \
 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 \
 	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
 	nrand48.c nrand48_r.c rand_r.c srand48.c srand48_r.c

+ 1 - 3
libc/stdlib/mkstemp.c

@@ -19,13 +19,11 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 
 
-extern int __gen_tempname (char *tmpl, int openit);
-
 /* Generate a unique temporary file name from TEMPLATE.
 /* Generate a unique temporary file name from TEMPLATE.
    The last six characters of TEMPLATE must be "XXXXXX";
    The last six characters of TEMPLATE must be "XXXXXX";
    they are replaced with a string that makes the filename unique.
    they are replaced with a string that makes the filename unique.
    Then open the file and return a fd. */
    Then open the file and return a fd. */
 int mkstemp (char *template)
 int mkstemp (char *template)
 {
 {
-    return __gen_tempname (template, 1);
+    return __gen_tempname (template, __GT_FILE);
 }
 }

+ 29 - 0
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);
+}

+ 1 - 3
libc/stdlib/mktemp.c

@@ -19,14 +19,12 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 
 
-extern int __gen_tempname (char *tmpl, int openit);
-
 /* Generate a unique temporary file name from TEMPLATE.
 /* Generate a unique temporary file name from TEMPLATE.
    The last six characters of TEMPLATE must be "XXXXXX";
    The last six characters of TEMPLATE must be "XXXXXX";
    they are replaced with a string that makes the filename unique.  */
    they are replaced with a string that makes the filename unique.  */
 char * mktemp (char *template)
 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.  */
 	/* We return the null string if we can't find a unique file name.  */
 	template[0] = '\0';
 	template[0] = '\0';