OSDN Git Service

libiberty:
[pf3gnuchains/gcc-fork.git] / libiberty / choose-temp.c
index 5668f74..1a475dd 100644 (file)
@@ -17,22 +17,24 @@ 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.  */
-
-#if defined (IN_GCC) || defined (HAVE_CONFIG_H)
+#ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-/* If we are in gcc, or we have a config.h, we assume that
-   HAVE_SYS_FILE_H tells us whether to include sys/file.h.  However,
-   libiberty does not have a config.h, and instead arranges to define
-   NO_SYS_FILE_H on the command line when there is no sys/file.h.  */
-
-#if (defined (IN_GCC) || defined (HAVE_CONFIG_H)) ? defined (HAVE_SYS_FILE_H) : ! defined (NO_SYS_FILE_H)
+#include <stdio.h>     /* May get P_tmpdir.  */
 #include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_SYS_FILE_H
 #include <sys/file.h>   /* May get R_OK, etc. on some systems.  */
 #endif
 
@@ -42,15 +44,11 @@ Boston, MA 02111-1307, USA.  */
 #define X_OK 1
 #endif
 
-#include <stdio.h>     /* May get P_tmpdir.  */
-
-#ifdef IN_GCC
-#include "gansidecl.h"
-extern char *xmalloc ();
-#else
-#include "ansidecl.h"
 #include "libiberty.h"
-#if defined (__MSDOS__) || defined (_WIN32)
+extern int mkstemps ();
+
+#ifndef IN_GCC
+#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN__) && ! defined (_UWIN))
 #define DIR_SEPARATOR '\\'
 #endif
 #endif
@@ -81,9 +79,11 @@ extern char *xmalloc ();
    If success, DIR is returned.
    Otherwise NULL is returned.  */
 
-static char *
+static const char *try PARAMS ((const char *, const char *));
+
+static const char *
 try (dir, base)
-     char *dir, *base;
+     const char *dir, *base;
 {
   if (base != 0)
     return base;
@@ -96,18 +96,20 @@ 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 ()
 {
-  char *base = 0;
+  const char *base = 0;
   char *temp_filename;
   int len;
   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);
@@ -124,24 +126,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);
@@ -149,3 +142,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)
+     const char *suffix;
+{
+  const 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;
+}