]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/choose-temp.c
Makefile.in (jc1, jv-scan): Link with $(SUBDIR_OBSTACK).
[thirdparty/gcc.git] / libiberty / choose-temp.c
CommitLineData
6599da04 1/* Utility to pick a temporary filename prefix.
b9fb3c42 2 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
6599da04
JM
3
4This file is part of the libiberty library.
5Libiberty is free software; you can redistribute it and/or
6modify it under the terms of the GNU Library General Public
7License as published by the Free Software Foundation; either
8version 2 of the License, or (at your option) any later version.
9
10Libiberty is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13Library General Public License for more details.
14
15You should have received a copy of the GNU Library General Public
16License along with libiberty; see the file COPYING.LIB. If not,
17write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18Boston, MA 02111-1307, USA. */
19
16ba4214 20/* This file exports two functions: choose_temp_base and make_temp_file. */
6599da04
JM
21
22/* This file lives in at least two places: libiberty and gcc.
23 Don't change one without the other. */
24
b9fb3c42 25#if defined (IN_GCC) || defined (HAVE_CONFIG_H)
84f79fea
JL
26#include "config.h"
27#endif
28
4cb1caaf
KG
29#ifdef IN_GCC
30#include "system.h"
31#else
32
33/* If we are in gcc, system.h has handled everything. When not in
34 gcc, if we have a config.h we assume that HAVE_SYS_FILE_H tells us
35 whether to include sys/file.h. However, libiberty does not have a
36 config.h, and instead arranges to define NO_SYS_FILE_H on the
37 command line when there is no sys/file.h. */
b9fb3c42 38
4cb1caaf 39#if defined (HAVE_CONFIG_H) ? defined (HAVE_SYS_FILE_H) : ! defined (NO_SYS_FILE_H)
6599da04
JM
40#include <sys/types.h>
41#include <sys/file.h> /* May get R_OK, etc. on some systems. */
42#endif
43
44#ifndef R_OK
45#define R_OK 4
46#define W_OK 2
47#define X_OK 1
48#endif
49
50#include <stdio.h> /* May get P_tmpdir. */
4cb1caaf 51#endif /* IN_GCC */
6599da04
JM
52
53#ifdef IN_GCC
6599da04 54extern char *xmalloc ();
91e0f659 55extern int mkstemps ();
6599da04
JM
56#else
57#include "ansidecl.h"
58#include "libiberty.h"
59#if defined (__MSDOS__) || defined (_WIN32)
60#define DIR_SEPARATOR '\\'
61#endif
62#endif
63
64#ifndef DIR_SEPARATOR
65#define DIR_SEPARATOR '/'
66#endif
67
68/* On MSDOS, write temp files in current dir
69 because there's no place else we can expect to use. */
70/* ??? Although the current directory is tried as a last resort,
84f79fea 71 this is left in so that on MSDOS it is preferred to /tmp on the
6599da04
JM
72 off chance that someone requires this, since that was the previous
73 behaviour. */
74#ifdef __MSDOS__
75#ifndef P_tmpdir
76#define P_tmpdir "."
77#endif
78#endif
79
80/* Name of temporary file.
81 mktemp requires 6 trailing X's. */
82#define TEMP_FILE "ccXXXXXX"
83
84/* Subroutine of choose_temp_base.
84f79fea 85 If BASE is non-NULL, return it.
6599da04
JM
86 Otherwise it checks if DIR is a usable directory.
87 If success, DIR is returned.
88 Otherwise NULL is returned. */
89
90static char *
91try (dir, base)
92 char *dir, *base;
93{
94 if (base != 0)
95 return base;
96 if (dir != 0
97 && access (dir, R_OK | W_OK | X_OK) == 0)
98 return dir;
99 return 0;
100}
101
102/* Return a prefix for temporary file names or NULL if unable to find one.
103 The current directory is chosen if all else fails so the program is
104 exited if a temporary directory can't be found (mktemp fails).
16ba4214
JL
105 The buffer for the result is obtained with xmalloc.
106
107 This function is provided for backwards compatability only. It use
108 is not recommended. */
6599da04
JM
109
110char *
111choose_temp_base ()
112{
113 char *base = 0;
114 char *temp_filename;
115 int len;
116 static char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 };
117 static char usrtmp[] = { DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
118
6599da04
JM
119 base = try (getenv ("TMPDIR"), base);
120 base = try (getenv ("TMP"), base);
121 base = try (getenv ("TEMP"), base);
122
123#ifdef P_tmpdir
124 base = try (P_tmpdir, base);
125#endif
126
127 /* Try /usr/tmp, then /tmp. */
128 base = try (usrtmp, base);
129 base = try (tmp, base);
130
131 /* If all else fails, use the current directory! */
132 if (base == 0)
6599da04 133 base = ".";
6599da04 134
6599da04
JM
135 len = strlen (base);
136 temp_filename = xmalloc (len + 1 /*DIR_SEPARATOR*/
137 + strlen (TEMP_FILE) + 1);
138 strcpy (temp_filename, base);
139
6599da04
JM
140 if (len != 0
141 && temp_filename[len-1] != '/'
142 && temp_filename[len-1] != DIR_SEPARATOR)
143 temp_filename[len++] = DIR_SEPARATOR;
6599da04
JM
144 strcpy (temp_filename + len, TEMP_FILE);
145
146 mktemp (temp_filename);
147 if (strlen (temp_filename) == 0)
148 abort ();
149 return temp_filename;
150}
16ba4214
JL
151/* Return a temporary file name (as a string) or NULL if unable to create
152 one. */
153
154char *
155make_temp_file (suffix)
156 char *suffix;
157{
158 char *base = 0;
159 char *temp_filename;
160 int base_len, suffix_len;
161 int fd;
162 static char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 };
163 static char usrtmp[] = { DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
164
165 base = try (getenv ("TMPDIR"), base);
166 base = try (getenv ("TMP"), base);
167 base = try (getenv ("TEMP"), base);
168
169#ifdef P_tmpdir
170 base = try (P_tmpdir, base);
171#endif
172
173 /* Try /usr/tmp, then /tmp. */
174 base = try (usrtmp, base);
175 base = try (tmp, base);
176
177 /* If all else fails, use the current directory! */
178 if (base == 0)
179 base = ".";
180
181 base_len = strlen (base);
182
183 if (suffix)
184 suffix_len = strlen (suffix);
185 else
186 suffix_len = 0;
187
188 temp_filename = xmalloc (base_len + 1 /*DIR_SEPARATOR*/
189 + strlen (TEMP_FILE)
190 + suffix_len + 1);
191 strcpy (temp_filename, base);
192
193 if (base_len != 0
194 && temp_filename[base_len-1] != '/'
195 && temp_filename[base_len-1] != DIR_SEPARATOR)
196 temp_filename[base_len++] = DIR_SEPARATOR;
197 strcpy (temp_filename + base_len, TEMP_FILE);
198
199 if (suffix)
200 strcat (temp_filename, suffix);
201
202 fd = mkstemps (temp_filename, suffix_len);
203 /* If mkstemps failed, then something bad is happening. Maybe we should
204 issue a message about a possible security attack in progress? */
205 if (fd == -1)
206 abort ();
207 /* Similarly if we can not close the file. */
208 if (close (fd))
209 abort ();
210 return temp_filename;
211}