From 16ba4214ee315678d2dabe417a71d09a9b867662 Mon Sep 17 00:00:00 2001 From: Jeffrey A Law Date: Sat, 5 Sep 1998 11:09:09 +0000 Subject: [PATCH] pexecute.c: Updates from gcc. * pexecute.c: Updates from gcc. Copy in gcc has been removed. This is the canonical copy. Define ISSPACE if !IN_GCC. * alloca.c, vfprintf.c, choose-temp.c, mkstemp.c: Similarly. * Makefile.in: Build mkstemp.o From-SVN: r22252 --- libiberty/ChangeLog | 2 + libiberty/Makefile.in | 5 +- libiberty/choose-temp.c | 78 ++++++++++++++++++++++---- libiberty/mkstemp.c | 121 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 192 insertions(+), 14 deletions(-) create mode 100644 libiberty/mkstemp.c diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 06e474adbb7..eb29aecc5d0 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -2,6 +2,8 @@ Sat Sep 5 03:24:49 1998 Jeffrey A Law (law@cygnus.com) * pexecute.c: Updates from gcc. Copy in gcc has been removed. This is the canonical copy. Define ISSPACE if !IN_GCC. + * alloca.c, vfprintf.c, choose-temp.c, mkstemp.c: Similarly. + * Makefile.in: Build mkstemp.o Wed Aug 19 14:05:01 1998 Mumit Khan diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index 9e6a0077331..edc6440f0d2 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -114,7 +114,7 @@ CFILES = asprintf.c alloca.c argv.c atexit.c basename.c bcmp.c bcopy.c \ bzero.c choose-temp.c clock.c concat.c cplus-dem.c fdmatch.c \ fnmatch.c getcwd.c getopt.c getopt1.c getpagesize.c \ getruntime.c floatformat.c hex.c index.c insque.c memchr.c \ - memcmp.c memcpy.c memmove.c memset.c objalloc.c obstack.c \ + memcmp.c memcpy.c memmove.c memset.c mkstemp.c objalloc.c obstack.c \ pexecute.c random.c rename.c rindex.c sigsetmask.c spaces.c \ strcasecmp.c strncasecmp.c strchr.c strdup.c strerror.c \ strrchr.c strsignal.c strstr.c strtod.c strtol.c strtoul.c \ @@ -124,7 +124,7 @@ CFILES = asprintf.c alloca.c argv.c atexit.c basename.c bcmp.c bcopy.c \ # These are always included in the library. REQUIRED_OFILES = argv.o choose-temp.o concat.o cplus-dem.o \ fdmatch.o fnmatch.o getopt.o getopt1.o getruntime.o hex.o \ - floatformat.o objalloc.o obstack.o pexecute.o spaces.o strerror.o \ + floatformat.o mkstemp.o objalloc.o obstack.o pexecute.o spaces.o strerror.o \ strsignal.o xatexit.o xexit.o xmalloc.o xstrdup.o xstrerror.o $(TARGETLIB): $(REQUIRED_OFILES) $(EXTRA_OFILES) $(LIBOBJS) @@ -229,6 +229,7 @@ getpagesize.o: config.h getruntime.o: config.h $(INCDIR)/libiberty.h hex.o: $(INCDIR)/libiberty.h floatformat.o: $(INCDIR)/floatformat.h +mkstemp.o: config.h objalloc.o: $(INCDIR)/objalloc.h obstack.o: $(INCDIR)/obstack.h pexecute.o: config.h $(INCDIR)/libiberty.h diff --git a/libiberty/choose-temp.c b/libiberty/choose-temp.c index ea4f9ed5f32..46293367613 100644 --- a/libiberty/choose-temp.c +++ b/libiberty/choose-temp.c @@ -17,7 +17,7 @@ License along with libiberty; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* This file exports one function: choose_temp_base. */ +/* This file exports two functions: choose_temp_base and make_temp_file. */ /* This file lives in at least two places: libiberty and gcc. Don't change one without the other. */ @@ -102,7 +102,10 @@ try (dir, base) /* Return a prefix for temporary file names or NULL if unable to find one. The current directory is chosen if all else fails so the program is exited if a temporary directory can't be found (mktemp fails). - The buffer for the result is obtained with xmalloc. */ + The buffer for the result is obtained with xmalloc. + + This function is provided for backwards compatability only. It use + is not recommended. */ char * choose_temp_base () @@ -113,7 +116,6 @@ choose_temp_base () static char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 }; static char usrtmp[] = { DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 }; -#ifndef MPW base = try (getenv ("TMPDIR"), base); base = try (getenv ("TMP"), base); base = try (getenv ("TEMP"), base); @@ -130,24 +132,15 @@ choose_temp_base () if (base == 0) base = "."; -#else /* MPW */ - base = ":"; -#endif - len = strlen (base); temp_filename = xmalloc (len + 1 /*DIR_SEPARATOR*/ + strlen (TEMP_FILE) + 1); strcpy (temp_filename, base); -#ifndef MPW if (len != 0 && temp_filename[len-1] != '/' && temp_filename[len-1] != DIR_SEPARATOR) temp_filename[len++] = DIR_SEPARATOR; -#else /* MPW */ - if (temp_filename[len-1] != ':') - temp_filename[len++] = ':'; -#endif /* MPW */ strcpy (temp_filename + len, TEMP_FILE); mktemp (temp_filename); @@ -155,3 +148,64 @@ choose_temp_base () abort (); return temp_filename; } +/* Return a temporary file name (as a string) or NULL if unable to create + one. */ + +char * +make_temp_file (suffix) + char *suffix; +{ + char *base = 0; + char *temp_filename; + int base_len, suffix_len; + int fd; + static char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 }; + static char usrtmp[] = { DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 }; + + base = try (getenv ("TMPDIR"), base); + base = try (getenv ("TMP"), base); + base = try (getenv ("TEMP"), base); + +#ifdef P_tmpdir + base = try (P_tmpdir, base); +#endif + + /* Try /usr/tmp, then /tmp. */ + base = try (usrtmp, base); + base = try (tmp, base); + + /* If all else fails, use the current directory! */ + if (base == 0) + base = "."; + + base_len = strlen (base); + + if (suffix) + suffix_len = strlen (suffix); + else + suffix_len = 0; + + temp_filename = xmalloc (base_len + 1 /*DIR_SEPARATOR*/ + + strlen (TEMP_FILE) + + suffix_len + 1); + strcpy (temp_filename, base); + + if (base_len != 0 + && temp_filename[base_len-1] != '/' + && temp_filename[base_len-1] != DIR_SEPARATOR) + temp_filename[base_len++] = DIR_SEPARATOR; + strcpy (temp_filename + base_len, TEMP_FILE); + + if (suffix) + strcat (temp_filename, suffix); + + fd = mkstemps (temp_filename, suffix_len); + /* If mkstemps failed, then something bad is happening. Maybe we should + issue a message about a possible security attack in progress? */ + if (fd == -1) + abort (); + /* Similarly if we can not close the file. */ + if (close (fd)) + abort (); + return temp_filename; +} diff --git a/libiberty/mkstemp.c b/libiberty/mkstemp.c new file mode 100644 index 00000000000..21afcf0d639 --- /dev/null +++ b/libiberty/mkstemp.c @@ -0,0 +1,121 @@ +/* Copyright (C) 1991, 1992, 1996, 1998 Free Software Foundation, Inc. + This file is derived from mkstemp.c from 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. */ + +#ifndef IN_GCC +#include +#include +#include +#include +#include +#include +#include +#else +#include "config.h" +#include "system.h" +#include "gansidecl.h" +#endif + +/* We need to provide a type for gcc_uint64_t. */ +#ifdef __GNUC__ +typedef unsigned long long gcc_uint64_t; +#else +typedef unsigned long gcc_uint64_t; +#endif + +#ifndef TMP_MAX +#define TMP_MAX 16384 +#endif + +/* Generate a unique temporary file name from TEMPLATE. + + TEMPLATE has the form: + + /ccXXXXXX + + SUFFIX_LEN tells us how long is (it can be zero length). + + The last six characters of TEMPLATE before 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 +mkstemps (template, suffix_len) + char *template; + int suffix_len; +{ + static const char letters[] + = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static gcc_uint64_t value; +#ifdef HAVE_GETTIMEOFDAY + struct timeval tv; +#endif + char *XXXXXX; + size_t len; + int count; + + len = strlen (template); + + if (len < 6 + suffix_len + || strncmp (&template[len - 6 - suffix_len], "XXXXXX", 6)) + { + return -1; + } + + XXXXXX = &template[len - 6 - suffix_len]; + +#ifdef HAVE_GETTIMEOFDAY + /* Get some more or less random data. */ + gettimeofday (&tv, NULL); + value += ((gcc_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); +#else + value += getpid (); +#endif + + for (count = 0; count < TMP_MAX; ++count) + { + gcc_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; +}