source: trunk/essentials/app-shells/bash/lib/sh/tmpfile.c

Last change on this file was 3268, checked in by bird, 18 years ago

Don't use the P_tmpdir #define and use the OS/2 TMP and TEMP variables as well to find a usable tmp location. Temporary files are always binary.

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1/*
2 * tmpfile.c - functions to create and safely open temp files for the shell.
3 */
4
5/* Copyright (C) 2000 Free Software Foundation, Inc.
6
7 This file is part of GNU Bash, the Bourne Again SHell.
8
9 Bash is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 Bash is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Bash; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22
23#include <config.h>
24
25#include <bashtypes.h>
26#include <posixstat.h>
27#include <posixtime.h>
28#include <filecntl.h>
29
30#if defined (HAVE_UNISTD_H)
31# include <unistd.h>
32#endif
33
34#include <stdio.h>
35#include <errno.h>
36
37#include <shell.h>
38
39#ifndef errno
40extern int errno;
41#endif
42
43#define BASEOPENFLAGS (O_CREAT | O_TRUNC | O_EXCL)
44
45#define DEFAULT_TMPDIR "." /* bogus default, should be changed */
46#define DEFAULT_NAMEROOT "shtmp"
47
48extern pid_t dollar_dollar_pid;
49
50static char *sys_tmpdir = (char *)NULL;
51static int ntmpfiles;
52static int tmpnamelen = -1;
53static unsigned long filenum = 1L;
54
55static char *
56get_sys_tmpdir ()
57{
58 struct stat sb;
59
60 if (sys_tmpdir)
61 return sys_tmpdir;
62
63#ifdef P_tmpdir
64# ifdef __OS2__ /* P_tmpdir is bogus ("."). */
65 sys_tmpdir = "/@unixroot/var/tmp";
66# else
67 sys_tmpdir = P_tmpdir;
68# endif
69 if (file_iswdir (sys_tmpdir))
70 return sys_tmpdir;
71#endif
72
73# ifdef __OS2__
74 sys_tmpdir = "/@unixroot/tmp";
75# else
76 sys_tmpdir = "/tmp";
77# endif
78 if (file_iswdir (sys_tmpdir))
79 return sys_tmpdir;
80
81#ifdef __OS2__
82 sys_tmpdir = "/@unixroot/var/tmp";
83#else
84 sys_tmpdir = "/var/tmp";
85#endif
86 if (file_iswdir (sys_tmpdir))
87 return sys_tmpdir;
88
89#ifdef __OS2__
90 sys_tmpdir = "/@unixroot/usr/tmp";
91#else
92 sys_tmpdir = "/usr/tmp";
93#endif
94 if (file_iswdir (sys_tmpdir))
95 return sys_tmpdir;
96
97#ifdef __OS2__
98 sys_tmpdir = get_string_value ("TMP");
99 if (file_iswdir (sys_tmpdir))
100 return sys_tmpdir;
101
102 sys_tmpdir = get_string_value ("TEMP");
103 if (file_iswdir (sys_tmpdir))
104 return sys_tmpdir;
105#endif
106
107 sys_tmpdir = DEFAULT_TMPDIR;
108
109 return sys_tmpdir;
110}
111
112static char *
113get_tmpdir (flags)
114 int flags;
115{
116 char *tdir;
117
118 tdir = (flags & MT_USETMPDIR) ? get_string_value ("TMPDIR") : (char *)NULL;
119 if (tdir == 0)
120 tdir = get_sys_tmpdir ();
121
122#if defined (HAVE_PATHCONF) && defined (_PC_NAME_MAX)
123 if (tmpnamelen == -1)
124 tmpnamelen = pathconf (tdir, _PC_NAME_MAX);
125#else
126 tmpnamelen = 0;
127#endif
128
129 return tdir;
130}
131
132char *
133sh_mktmpname (nameroot, flags)
134 char *nameroot;
135 int flags;
136{
137 char *filename, *tdir, *lroot;
138 struct stat sb;
139 int r, tdlen;
140
141 filename = (char *)xmalloc (PATH_MAX + 1);
142 tdir = get_tmpdir (flags);
143 tdlen = strlen (tdir);
144
145 lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
146
147#ifdef USE_MKTEMP
148 sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
149 if (mktemp (filename) == 0)
150 {
151 free (filename);
152 filename = NULL;
153 }
154#else /* !USE_MKTEMP */
155 while (1)
156 {
157 filenum = (filenum << 1) ^
158 (unsigned long) time ((time_t *)0) ^
159 (unsigned long) dollar_dollar_pid ^
160 (unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++);
161 sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
162 if (tmpnamelen > 0 && tmpnamelen < 32)
163 filename[tdlen + 1 + tmpnamelen] = '\0';
164# ifdef HAVE_LSTAT
165 r = lstat (filename, &sb);
166# else
167 r = stat (filename, &sb);
168# endif
169 if (r < 0 && errno == ENOENT)
170 break;
171 }
172#endif /* !USE_MKTEMP */
173
174 return filename;
175}
176
177int
178sh_mktmpfd (nameroot, flags, namep)
179 char *nameroot;
180 int flags;
181 char **namep;
182{
183 char *filename, *tdir, *lroot;
184 int fd, tdlen;
185
186 filename = (char *)xmalloc (PATH_MAX + 1);
187 tdir = get_tmpdir (flags);
188 tdlen = strlen (tdir);
189
190 lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
191
192#ifdef USE_MKSTEMP
193 sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
194 fd = mkstemp (filename);
195 if (fd < 0 || namep == 0)
196 {
197 free (filename);
198 filename = NULL;
199 }
200 if (namep)
201 *namep = filename;
202 return fd;
203#else /* !USE_MKSTEMP */
204 do
205 {
206 filenum = (filenum << 1) ^
207 (unsigned long) time ((time_t *)0) ^
208 (unsigned long) dollar_dollar_pid ^
209 (unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++);
210 sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum);
211 if (tmpnamelen > 0 && tmpnamelen < 32)
212 filename[tdlen + 1 + tmpnamelen] = '\0';
213# ifdef __OS2__
214 fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY) | O_BINARY, 0600);
215# else
216 fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY), 0600);
217# endif
218 }
219 while (fd < 0 && errno == EEXIST);
220
221 if (namep)
222 *namep = filename;
223 else
224 free (filename);
225
226 return fd;
227#endif /* !USE_MKSTEMP */
228}
229
230FILE *
231sh_mktmpfp (nameroot, flags, namep)
232 char *nameroot;
233 int flags;
234 char **namep;
235{
236 int fd;
237 FILE *fp;
238
239 fd = sh_mktmpfd (nameroot, flags, namep);
240 if (fd < 0)
241 return ((FILE *)NULL);
242#ifdef __OS2__
243 fp = fdopen (fd, (flags & MT_READWRITE) ? "w+b" : "wb");
244#else
245 fp = fdopen (fd, (flags & MT_READWRITE) ? "w+" : "w");
246#endif
247 if (fp == 0)
248 close (fd);
249 return fp;
250}
Note: See TracBrowser for help on using the repository browser.