OSDN Git Service

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