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 | |
parent | 2698e32c2c2fae23c5c5f39f73b09553158b482d (diff) | |
download | glibc-7cabd57c0d64a2ee5ca0c5218c877ff700727880.tar.gz glibc-7cabd57c0d64a2ee5ca0c5218c877ff700727880.tar.xz 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')
-rw-r--r-- | sysdeps/generic/getpgid.c | 4 | ||||
-rw-r--r-- | sysdeps/generic/glob.c | 2 | ||||
-rw-r--r-- | sysdeps/generic/mkstemp.c | 42 | ||||
-rw-r--r-- | sysdeps/generic/mktemp.c | 41 | ||||
-rw-r--r-- | sysdeps/generic/tempname.c | 46 | ||||
-rw-r--r-- | sysdeps/posix/mkstemp.c | 90 | ||||
-rw-r--r-- | sysdeps/posix/mktemp.c | 89 | ||||
-rw-r--r-- | sysdeps/posix/tempname.c | 287 |
8 files changed, 128 insertions, 473 deletions
diff --git a/sysdeps/generic/getpgid.c b/sysdeps/generic/getpgid.c index 7423e118f0..7ae21515b9 100644 --- a/sysdeps/generic/getpgid.c +++ b/sysdeps/generic/getpgid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1995, 1996, 1997, 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 @@ -20,7 +20,7 @@ #include <sys/types.h> /* Get the process group ID of process PID. */ -int +pid_t __getpgid (pid) pid_t pid; { diff --git a/sysdeps/generic/glob.c b/sysdeps/generic/glob.c index bd92d68324..5fc094ebe7 100644 --- a/sysdeps/generic/glob.c +++ b/sysdeps/generic/glob.c @@ -511,7 +511,7 @@ glob (pattern, flags, errfunc, pglob) case is nothing but a notation for a directory. */ if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~') { - dirname = (char *) pattern; + dirname = pattern; dirlen = strlen (pattern); /* Set FILENAME to NULL as a special flag. This is ugly but diff --git a/sysdeps/generic/mkstemp.c b/sysdeps/generic/mkstemp.c deleted file mode 100644 index c84e8eb4c2..0000000000 --- a/sysdeps/generic/mkstemp.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 1992, 1995, 1996 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 <stdlib.h> -#include <string.h> -#include <errno.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. - Returns a file descriptor open on the file for reading and writing. */ -int -mkstemp (template) - char *template; -{ - if (strcmp (&template[strlen (template) - 6], "XXXXXX")) - { - __set_errno (EINVAL); - return -1; - } - - __set_errno (ENOSYS); - return -1; -} - -stub_warning (mkstemp) -#include <stub-tag.h> diff --git a/sysdeps/generic/mktemp.c b/sysdeps/generic/mktemp.c deleted file mode 100644 index 7d53f01c04..0000000000 --- a/sysdeps/generic/mktemp.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 1991, 1995, 1996 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 <stdlib.h> -#include <string.h> -#include <errno.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. */ -char * -mktemp (template) - char *template; -{ - if (strcmp (&template[strlen (template) - 6], "XXXXXX")) - { - __set_errno (EINVAL); - return template; - } - - __set_errno (ENOSYS); - return NULL; -} - -stub_warning (mktemp) -#include <stub-tag.h> diff --git a/sysdeps/generic/tempname.c b/sysdeps/generic/tempname.c index f5d1ed0345..c17d86967d 100644 --- a/sysdeps/generic/tempname.c +++ b/sysdeps/generic/tempname.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 93, 95, 96, 97 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 93, 95, 96, 97, 98 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 @@ -16,31 +16,39 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <errno.h> +#define __need_size_t +#include <stddef.h> #include <stdio.h> +#include <errno.h> -/* Generate a (hopefully) unique temporary filename - in DIR (if applicable), using prefix PFX. - If DIR_SEARCH is nonzero, perform directory searching - malarkey as per the SVID for tempnam. - Return the generated filename or NULL if one could not - be generated, putting the length of the string in *LENPTR. */ -char * -__stdio_gen_tempname (buf, bufsize, dir, pfx, dir_search, lenptr, streamptr, - large_file) - char *buf; - size_t bufsize; +/* Perform the "SVID path search malarkey" on DIR and PFX. Write a + template suitable for use in __gen_tempname into TMPL, bounded + by TMPL_LEN. */ +int +__path_search (tmpl, tmpl_len, dir, pfx) + char *tmpl; + size_t tmpl_len; const char *dir; const char *pfx; - int dir_search; - size_t *lenptr; - FILE **streamptr; +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (__path_search) + +/* Generate a (hopefully) unique temporary filename + in DIR (if applicable), using template TMPL. + If OPENIT is 1, open the file and return a fd. If LARGEFILE is 1, + use open64() to do that. */ + int + __gen_tempname (tmpl, openit, largefile) + char *tmpl; + int openit; int large_file; { - *lenptr = 0; __set_errno (ENOSYS); - return NULL; + return -1; } -stub_warning (__stdio_gen_tempname) +stub_warning (__gen_tempname) #include <stub-tag.h> diff --git a/sysdeps/posix/mkstemp.c b/sysdeps/posix/mkstemp.c deleted file mode 100644 index d380935c42..0000000000 --- a/sysdeps/posix/mkstemp.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (C) 1991, 1992, 1996, 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 <stdlib.h> -#include <string.h> -#include <errno.h> -#include <stdint.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/time.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. - Returns a file descriptor open on the file for reading and writing. */ -int -mkstemp (template) - char *template; -{ - static const char letters[62] - = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static uint64_t value; - struct timeval tv; - char *XXXXXX; - size_t len; - int count; - - len = strlen (template); - if (len < 6 || strcmp (&template[len - 6], "XXXXXX")) - { - __set_errno (EINVAL); - return -1; - } - - /* This is where the Xs start. */ - XXXXXX = &template[len - 6]; - - /* Get some more or less random data. */ - __gettimeofday (&tv, NULL); - value += ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ __getpid (); - - for (count = 0; count < TMP_MAX; ++count) - { - uint64_t v = value; - int fd; - - /* 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]; - - fd = __open (template, O_RDWR|O_CREAT|O_EXCL, 0600); - if (fd >= 0) - /* The file does not exist. */ - return fd; - - /* This is a random value. It is only necessary that the next - TMP_MAX values generated by adding 7777 to VALUE are different - with (module 2^32). */ - value += 7777; - } - - /* We return the null string if we can't find a unique file name. */ - template[0] = '\0'; - return -1; -} diff --git a/sysdeps/posix/mktemp.c b/sysdeps/posix/mktemp.c deleted file mode 100644 index e9a576c16f..0000000000 --- a/sysdeps/posix/mktemp.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (C) 1991, 1992, 1993, 1996, 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 <errno.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.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. */ -char * -mktemp (template) - char *template; -{ - static const char letters[] - = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static uint64_t value; - struct timeval tv; - char *XXXXXX; - size_t len; - int count; - - len = strlen (template); - if (len < 6 || strcmp (&template[len - 6], "XXXXXX")) - { - __set_errno (EINVAL); - return NULL; - } - - /* This is where the Xs start. */ - XXXXXX = &template[len - 6]; - - /* Get some more or less random data. */ - __gettimeofday (&tv, NULL); - value += ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ __getpid (); - - for (count = 0; count < TMP_MAX; ++count) - { - struct stat ignored; - 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]; - - if (stat (template, &ignored) < 0 && errno == ENOENT) - /* The file does not exist. So return this name. */ - return template; - - /* This is a random value. It is only necessary that the next - TMP_MAX values generated by adding 7777 to VALUE are different - with (module 2^32). */ - value += 7777; - } - - /* We return the null string if we can't find a unique file name. */ - template[0] = '\0'; - return template; -} 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; } |