00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023
00024 #include <stdio.h>
00025 #include <sys/types.h>
00026 #ifdef HAVE_UNISTD_H
00027 #include <unistd.h>
00028 #endif
00029 #ifdef HAVE_STDLIB_H
00030 #include <stdlib.h>
00031 #endif
00032 #ifdef HAVE_STRING_H
00033 #include <string.h>
00034 #endif
00035 #ifdef HAVE_SYS_FILE_H
00036 #include <sys/file.h>
00037 #endif
00038
00039 #ifndef R_OK
00040 #define R_OK 4
00041 #define W_OK 2
00042 #define X_OK 1
00043 #endif
00044
00045 #include "libiberty.h"
00046 extern int mkstemps (char *, int);
00047
00048
00049 #ifndef DIR_SEPARATOR
00050 #define DIR_SEPARATOR '/'
00051 #endif
00052
00053
00054
00055 #define TEMP_FILE "ccXXXXXX"
00056 #define TEMP_FILE_LEN (sizeof(TEMP_FILE) - 1)
00057
00058
00059
00060
00061
00062
00063
00064 static inline const char *try_dir (const char *, const char *);
00065
00066 static inline const char *
00067 try_dir (const char *dir, const char *base)
00068 {
00069 if (base != 0)
00070 return base;
00071 if (dir != 0
00072 && access (dir, R_OK | W_OK | X_OK) == 0)
00073 return dir;
00074 return 0;
00075 }
00076
00077 static const char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 };
00078 static const char usrtmp[] =
00079 { DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
00080 static const char vartmp[] =
00081 { DIR_SEPARATOR, 'v', 'a', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
00082
00083 static char *memoized_tmpdir;
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 char *
00097 choose_tmpdir (void)
00098 {
00099 const char *base = 0;
00100 char *tmpdir;
00101 unsigned int len;
00102
00103 if (memoized_tmpdir)
00104 return memoized_tmpdir;
00105
00106 base = try_dir (getenv ("TMPDIR"), base);
00107 base = try_dir (getenv ("TMP"), base);
00108 base = try_dir (getenv ("TEMP"), base);
00109
00110 #ifdef P_tmpdir
00111 base = try_dir (P_tmpdir, base);
00112 #endif
00113
00114
00115 base = try_dir (vartmp, base);
00116 base = try_dir (usrtmp, base);
00117 base = try_dir (tmp, base);
00118
00119
00120 if (base == 0)
00121 base = ".";
00122
00123
00124
00125 len = strlen (base);
00126 tmpdir = XNEWVEC (char, len + 2);
00127 strcpy (tmpdir, base);
00128 tmpdir[len] = DIR_SEPARATOR;
00129 tmpdir[len+1] = '\0';
00130
00131 memoized_tmpdir = tmpdir;
00132 return tmpdir;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 char *
00148 make_temp_file (const char *suffix)
00149 {
00150 const char *base = choose_tmpdir ();
00151 char *temp_filename;
00152 int base_len, suffix_len;
00153 int fd;
00154
00155 if (suffix == 0)
00156 suffix = "";
00157
00158 base_len = strlen (base);
00159 suffix_len = strlen (suffix);
00160
00161 temp_filename = XNEWVEC (char, base_len
00162 + TEMP_FILE_LEN
00163 + suffix_len + 1);
00164 strcpy (temp_filename, base);
00165 strcpy (temp_filename + base_len, TEMP_FILE);
00166 strcpy (temp_filename + base_len + TEMP_FILE_LEN, suffix);
00167
00168 fd = mkstemps (temp_filename, suffix_len);
00169
00170
00171 if (fd == -1)
00172 abort ();
00173
00174 if (close (fd))
00175 abort ();
00176 return temp_filename;
00177 }