diff options
author | Ulrich Drepper <drepper@redhat.com> | 1998-08-03 16:47:01 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1998-08-03 16:47:01 +0000 |
commit | 7cabd57c0d64a2ee5ca0c5218c877ff700727880 (patch) | |
tree | 4db8d28a07bfb0ee5705e9199fcf1f59d5b27403 /sysdeps/posix/tempname.c | |
parent | 2698e32c2c2fae23c5c5f39f73b09553158b482d (diff) | |
download | glibc-7cabd57c0d64a2ee5ca0c5218c877ff700727880.tar glibc-7cabd57c0d64a2ee5ca0c5218c877ff700727880.tar.gz glibc-7cabd57c0d64a2ee5ca0c5218c877ff700727880.tar.bz2 glibc-7cabd57c0d64a2ee5ca0c5218c877ff700727880.zip |
Update.
1998-08-03 16:36 Ulrich Drepper <drepper@cygnus.com>
* catgets/catgets.c: Use mmap/munmap only is _POSIX_MAPPED_FILES
is defined.
* catgets/open_catalog.c: Likewise.
* iconv/iconv_prog.c: Likewise.
* intl/loadmsgcat.c: Likewise.
* locale/findlocale.c: Likewise.
* locale/loadlocale.c: Likewise.
* locale/programs/localedef.c: Likewise.
* malloc/malloc.c: Likewise.
* elf/elf.h: Fix typo.
* math/Makefile: Use $(LN_S) instead of ln.
* sysdeps/generic/getpgid.c: Fix return type.
1998-08-01 02:49 -0400 Zack Weinberg <zack@rabi.phys.columbia.edu>
* sysdeps/posix/tempname.c (__stdio_gen_tempname): Rename to
__gen_tempname and simplify the interface. Strip out the
code to do path search and create FILE objects. This function
now takes a mktemp() style template and returns either a name
or a file descriptor.
(__path_search): New function; searches for directories for
temp files.
* sysdeps/generic/tempname.c: Stub out __gen_tempname and
__path_search, not __stdio_gen_tempname.
* libio/stdio.h: Prototype __gen_tempname and __path_search,
not __stdio_gen_tempname.
* stdio/stdio.h: Likewise.
* stdio-common/tempnam.c: Use __path_search and __gen_tempname.
* stdio-common/tmpfile.c: Likewise.
* stdio-common/tmpfile64.c: Likewise.
* stdio-common/tmpnam.c: Likewise.
* stdio-common/tmpnam_r.c: Likewise.
* misc/mkstemp.c: New file. Use __gen_tempname.
* misc/mktemp.c: Likewise.
* sysdeps/posix/mkstemp.c: Removed.
* sysdeps/posix/mktemp.c: Removed.
* sysdeps/generic/mkstemp.c: Removed.
* sysdeps/generic/mktemp.c: Removed.
1998-08-02 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
* configure.in: Check, if door add-on is installed.
* config.make.in: Add have_doors.
* sunrpc/Makefile: Add HAVE_DOOR define.
* sunrpc/key_call.c: Add keyserv/door interface.
* sunrpc/svc_unix.c: Call setsockopt only if SO_PASSCRED is defined.
* sunrpc/clnt_unix.c: Likewise.
1998-08-02 Andreas Jaeger <aj@arthur.rhein-neckar.de>
* inet/netinet/in.h (IN_CLASSC): Correct mask.
Reported by Ian Staniforth <I.Staniforth@sheffield.ac.uk> [fixes
PR libc/727].
1998-08-03 10:23 Ulrich Drepper <drepper@cygnus.com>
* misc/Makefile: Fix installation problem with --disable-shared.
* posix/Makefile: Likewise.
1998-08-02 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* posix/regex.c (re_search_2): Optimize searching for anchored
pattern if '^' cannot match at embedded newlines.
(regerror): Renamed from __regerror, which it should only be
called if _LIBC.
1998-07-31 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sunrpc/svc_unix.c (__msgread): Check setsockopt return value.
1998-07-31 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/generic/glob.c: Remove obsolete cast.
1998-07-31 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* Rules (tests): Fix last change.
Diffstat (limited to 'sysdeps/posix/tempname.c')
-rw-r--r-- | sysdeps/posix/tempname.c | 287 |
1 files changed, 98 insertions, 189 deletions
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c index 82e0243132..6dd893e613 100644 --- a/sysdeps/posix/tempname.c +++ b/sysdeps/posix/tempname.c @@ -28,119 +28,99 @@ #include <unistd.h> #include <sys/time.h> -#ifdef USE_IN_LIBIO -# include "libioP.h" -# include <libio.h> -#endif - /* Return nonzero if DIR is an existent directory. */ static int -diraccess (const char *dir) +direxists (const char *dir) { struct stat buf; return __stat (dir, &buf) == 0 && S_ISDIR (buf.st_mode); } -/* Return nonzero if FILE exists. */ -static int -exists (const char *file) +/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is + non-null and exists, uses it; otherwise uses the first of $TMPDIR, + P_tmpdir, /tmp that exists. Copies into TMPL a template suitable + 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) { - /* We can stat the file even if we can't read its data. */ - struct stat st; - int save = errno; - if (__stat (file, &st) == 0) - return 1; + const char *d; + size_t dlen, plen; + + if (!pfx || !pfx[0]) + { + pfx = "file"; + plen = 4; + } else { - /* We report that the file exists if stat failed for a reason other - than nonexistence. In this case, it may or may not exist, and we - don't know; but reporting that it does exist will never cause any - trouble, while reporting that it doesn't exist when it does would - violate the interface of __stdio_gen_tempname. */ - int exists = errno != ENOENT; - __set_errno (save); - return exists; + plen = strlen (pfx); + if (plen > 5) + plen = 5; } -} - -/* These are the characters used in temporary filenames. */ -static const char letters[] = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - -/* Generate a temporary filename and return it (in a static buffer). If - STREAMPTR is not NULL, open a stream "w+b" on the file and set - *STREAMPTR to it. If DIR_SEARCH is nonzero, DIR and PFX are used as - described for tempnam. If not, a temporary filename in P_tmpdir with no - special prefix is generated. If LENPTR is not NULL, *LENPTR is set the - to length (including the terminating '\0') of the resultant filename, - which is returned. This goes through a cyclic pattern of all possible - filenames consisting of five decimal digits of the current pid and three - of the characters in `letters'. Data for tempnam and tmpnam is kept - separate, but when tempnam is using P_tmpdir and no prefix (i.e, it is - identical to tmpnam), the same data is used. Each potential filename is - tested for an already-existing file of the same name, and no name of an - existing file will be returned. When the cycle reaches its end - (12345ZZZ), NULL is returned. */ -char * -__stdio_gen_tempname (char *buf, size_t bufsize, const char *dir, - const char *pfx, int dir_search, size_t *lenptr, - FILE **streamptr, int large_file) -{ - int saverrno = errno; - static const char tmpdir[] = P_tmpdir; - size_t plen, dlen, len; - char *XXXXXX; - static uint64_t value; - struct timeval tv; - int count; - - if (dir_search) + d = __secure_getenv ("TMPDIR"); + if (d != NULL && direxists (d)) + dir = d; + else if (dir != NULL && direxists (dir)) + /* nothing */ ; + else if (direxists (P_tmpdir)) + dir = P_tmpdir; + else if (direxists ("/tmp")) + dir = "/tmp"; + else { - register const char *d = __secure_getenv ("TMPDIR"); - if (d != NULL && !diraccess (d)) - d = NULL; - if (d == NULL && dir != NULL && diraccess (dir)) - d = dir; - if (d == NULL && diraccess (tmpdir)) - d = tmpdir; - if (d == NULL && diraccess ("/tmp")) - d = "/tmp"; - if (d == NULL) - { - __set_errno (ENOENT); - return NULL; - } - dir = d; + __set_errno (ENOENT); + return -1; } - else - dir = tmpdir; dlen = strlen (dir); - - /* Remove trailing slashes from the directory name. */ while (dlen > 1 && dir[dlen - 1] == '/') - --dlen; + dlen--; /* remove trailing slashes */ - if (pfx != NULL && *pfx != '\0') + /* check we have room for "${dir}/${pfx}XXXXXX\0" */ + if (tmpl_len < dlen + 1 + plen + 6 + 1) { - plen = strlen (pfx); - if (plen > 5) - plen = 5; + __set_errno (EINVAL); + return -1; } - else - plen = 0; - len = __snprintf (buf, bufsize, "%.*s/%.*sXXXXXX", - (int) dlen, dir, (int) plen, pfx); + sprintf (tmpl, "%*s/%*sXXXXXX", dlen, dir, plen, pfx); + return 0; +} + +/* These are the characters used in temporary filenames. */ +static const char letters[] = +"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +/* 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(). + + We use a clever algorithm to get hard-to-predict names. */ +int +__gen_tempname (char *tmpl, int openit, int largefile) +{ + int len; + char *XXXXXX; + static uint64_t value; + struct timeval tv; + int count, fd; + int save_errno = errno; - if (len < dlen + plen + 7) - { + len = strlen (tmpl); + if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX")) + { __set_errno (EINVAL); - return NULL; - } + return -1; + } - XXXXXX = &buf[dlen + plen + 1]; + /* This is where the Xs start. */ + XXXXXX = &tmpl[len - 6]; /* Get some more or less random data. */ __gettimeofday (&tv, NULL); @@ -163,116 +143,45 @@ __stdio_gen_tempname (char *buf, size_t bufsize, const char *dir, v /= 62; XXXXXX[5] = letters[v % 62]; - if (streamptr != NULL) + if (openit) { - /* Try to create the file atomically. */ -#ifdef _G_OPEN64 - int fd = (large_file - ? __open (buf, O_RDWR|O_CREAT|O_EXCL, 0666) - : _G_OPEN64 (buf, O_RDWR|O_CREAT|O_EXCL, 0666)); + /* XXX Do we want to fail on largefile if 64 bit fileops + are not implemented, or just fall back to the old stuff? */ +#ifndef __stub_open64 + fd = (largefile + ? __open (tmpl, O_RDWR | O_CREAT | O_EXCL, 0666) + : __open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, 0666)); #else - int fd = __open (buf, O_RDWR|O_CREAT|O_EXCL, 0666); + fd = __open (tmpl, O_RDWR | O_CREAT | O_EXCL, 0666); #endif if (fd >= 0) { - /* We got a new file that did not previously exist. - Create a stream for it. */ -#ifdef USE_IN_LIBIO - int save; - struct locked_FILE - { - struct _IO_FILE_plus fp; -#ifdef _IO_MTSAFE_IO - _IO_lock_t lock; -#endif - } *new_f; - struct _IO_FILE_plus *fp; - - new_f = (struct locked_FILE *) - malloc (sizeof (struct locked_FILE)); - if (new_f == NULL) - { - /* We lost trying to create a stream (out of memory?). - Nothing to do but remove the file, close the descriptor, - and return failure. */ - save = errno; - lose: - (void) remove (buf); - (void) __close (fd); - __set_errno (save); - return NULL; - } - fp = &new_f->fp; -#ifdef _IO_MTSAFE_IO - fp->file._lock = &new_f->lock; -#endif - _IO_init (&fp->file, 0); - _IO_JUMPS (&fp->file) = &_IO_file_jumps; - _IO_file_init (&fp->file); -# if !_IO_UNIFIED_JUMPTABLES - fp->vtable = NULL; -# endif - if (_IO_file_attach (&fp->file, fd) == NULL) - { - save = errno; - free (fp); - goto lose; - } - fp->file._flags &= ~_IO_DELETE_DONT_CLOSE; - - *streamptr = (FILE *) fp; -#else - *streamptr = __newstream (); - if (*streamptr == NULL) + __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) { - /* We lost trying to create a stream (out of memory?). - Nothing to do but remove the file, close the descriptor, - and return failure. */ - const int save = errno; - (void) remove (buf); - (void) __close (fd); - __set_errno (save); - return NULL; + __set_errno (save_errno); + return 0; } - (*streamptr)->__cookie = (__ptr_t) (long int) fd; - (*streamptr)->__mode.__write = 1; - (*streamptr)->__mode.__read = 1; - (*streamptr)->__mode.__binary = 1; -#endif + else + /* Give up now. */ + return -1; } -#if defined EMFILE || defined ENFILE || defined EINTR - else if (0 -# ifdef EMFILE - || errno == EMFILE -# endif -# ifdef ENFILE - || errno == ENFILE -# endif -# ifdef EINTR - || errno == EINTR -# endif - ) - /* We cannot open anymore files since all descriptors are - used or because we got a signal. */ - return NULL; -#endif - else - continue; } - else if (exists (buf)) - continue; - - /* If the file already existed we have continued the loop above, - so we only get here when we have a winning name to return. */ - - __set_errno (saverrno); - - if (lenptr != NULL) - *lenptr = len + 1; - return buf; } /* We got out of the loop because we ran out of combinations to try. */ - __set_errno (EEXIST); /* ? */ - return NULL; + __set_errno (EEXIST); + return -1; } |