Mercurial > gnulib
annotate lib/clean-temp.c @ 9309:bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 07 Oct 2007 19:14:58 +0200 |
parents | a162347a0232 |
children | e8d2c6fc33ad |
rev | line source |
---|---|
7044 | 1 /* Temporary directories and temporary files with automatic cleanup. |
8161
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
2 Copyright (C) 2001, 2003, 2006-2007 Free Software Foundation, Inc. |
7044 | 3 Written by Bruno Haible <bruno@clisp.org>, 2006. |
4 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8948
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
7044 | 6 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8948
diff
changeset
|
7 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8948
diff
changeset
|
8 (at your option) any later version. |
7044 | 9 |
10 This program 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 | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8948
diff
changeset
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
7044 | 17 |
18 | |
7304
1c4ed7637c24
Include <config.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
7044
diff
changeset
|
19 #include <config.h> |
7044 | 20 |
21 /* Specification. */ | |
22 #include "clean-temp.h" | |
23 | |
24 #include <errno.h> | |
7417
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
25 #include <fcntl.h> |
7044 | 26 #include <limits.h> |
27 #include <stdbool.h> | |
28 #include <stdlib.h> | |
29 #include <string.h> | |
30 #include <unistd.h> | |
31 | |
8161
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
32 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
33 # define WIN32_LEAN_AND_MEAN /* avoid including junk */ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
34 # include <windows.h> |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
35 #endif |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
36 |
7044 | 37 #include "error.h" |
38 #include "fatal-signal.h" | |
39 #include "pathmax.h" | |
40 #include "tmpdir.h" | |
41 #include "xalloc.h" | |
8948
a162347a0232
Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents:
8438
diff
changeset
|
42 #include "xmalloca.h" |
7044 | 43 #include "gl_linkedhash_list.h" |
44 #include "gettext.h" | |
7513 | 45 #if GNULIB_FWRITEERROR |
46 # include "fwriteerror.h" | |
47 #endif | |
7417
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
48 #if GNULIB_CLOSE_STREAM |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
49 # include "close-stream.h" |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
50 #endif |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
51 #if GNULIB_FCNTL_SAFER |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
52 # include "fcntl--.h" |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
53 #endif |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
54 #if GNULIB_FOPEN_SAFER |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
55 # include "stdio--.h" |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
56 #endif |
7044 | 57 |
58 #define _(str) gettext (str) | |
59 | |
7414
368fbbd8e59d
Provide a fallback for PATH_MAX.
Bruno Haible <bruno@clisp.org>
parents:
7411
diff
changeset
|
60 /* GNU Hurd doesn't have PATH_MAX. */ |
368fbbd8e59d
Provide a fallback for PATH_MAX.
Bruno Haible <bruno@clisp.org>
parents:
7411
diff
changeset
|
61 #ifndef PATH_MAX |
368fbbd8e59d
Provide a fallback for PATH_MAX.
Bruno Haible <bruno@clisp.org>
parents:
7411
diff
changeset
|
62 # ifdef MAXPATHLEN |
368fbbd8e59d
Provide a fallback for PATH_MAX.
Bruno Haible <bruno@clisp.org>
parents:
7411
diff
changeset
|
63 # define PATH_MAX MAXPATHLEN |
368fbbd8e59d
Provide a fallback for PATH_MAX.
Bruno Haible <bruno@clisp.org>
parents:
7411
diff
changeset
|
64 # else |
368fbbd8e59d
Provide a fallback for PATH_MAX.
Bruno Haible <bruno@clisp.org>
parents:
7411
diff
changeset
|
65 # define PATH_MAX 1024 |
368fbbd8e59d
Provide a fallback for PATH_MAX.
Bruno Haible <bruno@clisp.org>
parents:
7411
diff
changeset
|
66 # endif |
368fbbd8e59d
Provide a fallback for PATH_MAX.
Bruno Haible <bruno@clisp.org>
parents:
7411
diff
changeset
|
67 #endif |
368fbbd8e59d
Provide a fallback for PATH_MAX.
Bruno Haible <bruno@clisp.org>
parents:
7411
diff
changeset
|
68 |
7411
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
69 #ifndef uintptr_t |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
70 # define uintptr_t unsigned long |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
71 #endif |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
72 |
7863 | 73 #if !GNULIB_FCNTL_SAFER |
74 /* The results of open() in this file are not used with fchdir, | |
75 therefore save some unnecessary work in fchdir.c. */ | |
76 # undef open | |
77 # undef close | |
78 #endif | |
79 | |
7044 | 80 |
81 /* The use of 'volatile' in the types below (and ISO C 99 section 5.1.2.3.(5)) | |
82 ensure that while constructing or modifying the data structures, the field | |
83 values are written to memory in the order of the C statements. So the | |
84 signal handler can rely on these field values to be up to date. */ | |
85 | |
86 | |
87 /* Registry for a single temporary directory. | |
88 'struct temp_dir' from the public header file overlaps with this. */ | |
89 struct tempdir | |
90 { | |
91 /* The absolute pathname of the directory. */ | |
92 char * volatile dirname; | |
93 /* Whether errors during explicit cleanup are reported to standard error. */ | |
94 bool cleanup_verbose; | |
95 /* Absolute pathnames of subdirectories. */ | |
96 gl_list_t /* <char *> */ volatile subdirs; | |
97 /* Absolute pathnames of files. */ | |
98 gl_list_t /* <char *> */ volatile files; | |
99 }; | |
100 | |
101 /* List of all temporary directories. */ | |
102 static struct | |
103 { | |
104 struct tempdir * volatile * volatile tempdir_list; | |
105 size_t volatile tempdir_count; | |
106 size_t tempdir_allocated; | |
107 } cleanup_list /* = { NULL, 0, 0 } */; | |
108 | |
7411
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
109 /* List of all open file descriptors to temporary files. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
110 static gl_list_t /* <int> */ volatile descriptors; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
111 |
7044 | 112 |
113 /* For the subdirs and for the files, we use a gl_list_t of type LINKEDHASH. | |
114 Why? We need a data structure that | |
115 | |
116 1) Can contain an arbitrary number of 'char *' values. The strings | |
117 are compared via strcmp, not pointer comparison. | |
118 2) Has insertion and deletion operations that are fast: ideally O(1), | |
119 or possibly O(log n). This is important for GNU sort, which may | |
120 create a large number of temporary files. | |
121 3) Allows iteration through all elements from within a signal handler. | |
122 4) May or may not allow duplicates. It doesn't matter here, since | |
123 any file or subdir can only be removed once. | |
124 | |
125 Criterion 1) would allow any gl_list_t or gl_oset_t implementation. | |
126 | |
127 Criterion 2) leaves only GL_LINKEDHASH_LIST, GL_TREEHASH_LIST, or | |
128 GL_TREE_OSET. | |
129 | |
130 Criterion 3) puts at disadvantage GL_TREEHASH_LIST and GL_TREE_OSET. | |
131 Namely, iteration through the elements of a binary tree requires access | |
132 to many ->left, ->right, ->parent pointers. However, the rebalancing | |
133 code for insertion and deletion in an AVL or red-black tree is so | |
134 complicated that we cannot assume that >left, ->right, ->parent pointers | |
135 are in a consistent state throughout these operations. Therefore, to | |
136 avoid a crash in the signal handler, all destructive operations to the | |
137 lists would have to be protected by a | |
138 block_fatal_signals (); | |
139 ... | |
140 unblock_fatal_signals (); | |
141 pair. Which causes extra system calls. | |
142 | |
143 Criterion 3) would also discourage GL_ARRAY_LIST and GL_CARRAY_LIST, | |
144 if they were not already excluded. Namely, these implementations use | |
145 xrealloc(), leaving a time window in which in the list->elements pointer | |
146 points to already deallocated memory. To avoid a crash in the signal | |
147 handler at such a moment, all destructive operations would have to | |
148 protected by block/unblock_fatal_signals (), in this case too. | |
149 | |
150 A list of type GL_LINKEDHASH_LIST without duplicates fulfills all | |
151 requirements: | |
152 2) Insertion and deletion are O(1) on average. | |
153 3) The gl_list_iterator, gl_list_iterator_next implementations do | |
154 not trigger memory allocations, nor other system calls, and are | |
155 therefore safe to be called from a signal handler. | |
156 Furthermore, since SIGNAL_SAFE_LIST is defined, the implementation | |
157 of the destructive functions ensures that the list structure is | |
158 safe to be traversed at any moment, even when interrupted by an | |
159 asynchronous signal. | |
160 */ | |
161 | |
162 /* String equality and hash code functions used by the lists. */ | |
163 | |
164 static bool | |
165 string_equals (const void *x1, const void *x2) | |
166 { | |
7586
4a8b5467d8b2
Make it compile in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
7513
diff
changeset
|
167 const char *s1 = (const char *) x1; |
4a8b5467d8b2
Make it compile in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
7513
diff
changeset
|
168 const char *s2 = (const char *) x2; |
7044 | 169 return strcmp (s1, s2) == 0; |
170 } | |
171 | |
172 #define SIZE_BITS (sizeof (size_t) * CHAR_BIT) | |
173 | |
174 /* A hash function for NUL-terminated char* strings using | |
175 the method described by Bruno Haible. | |
176 See http://www.haible.de/bruno/hashfunc.html. */ | |
177 static size_t | |
178 string_hash (const void *x) | |
179 { | |
7586
4a8b5467d8b2
Make it compile in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
7513
diff
changeset
|
180 const char *s = (const char *) x; |
7044 | 181 size_t h = 0; |
182 | |
183 for (; *s; s++) | |
184 h = *s + ((h << 9) | (h >> (SIZE_BITS - 9))); | |
185 | |
186 return h; | |
187 } | |
188 | |
189 | |
190 /* The signal handler. It gets called asynchronously. */ | |
191 static void | |
192 cleanup () | |
193 { | |
194 size_t i; | |
195 | |
7411
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
196 /* First close all file descriptors to temporary files. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
197 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
198 gl_list_t fds = descriptors; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
199 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
200 if (fds != NULL) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
201 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
202 gl_list_iterator_t iter; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
203 const void *element; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
204 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
205 iter = gl_list_iterator (fds); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
206 while (gl_list_iterator_next (&iter, &element, NULL)) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
207 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
208 int fd = (int) (uintptr_t) element; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
209 close (fd); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
210 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
211 gl_list_iterator_free (&iter); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
212 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
213 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
214 |
7044 | 215 for (i = 0; i < cleanup_list.tempdir_count; i++) |
216 { | |
217 struct tempdir *dir = cleanup_list.tempdir_list[i]; | |
218 | |
219 if (dir != NULL) | |
220 { | |
221 gl_list_iterator_t iter; | |
222 const void *element; | |
223 | |
224 /* First cleanup the files in the subdirectories. */ | |
225 iter = gl_list_iterator (dir->files); | |
226 while (gl_list_iterator_next (&iter, &element, NULL)) | |
227 { | |
228 const char *file = (const char *) element; | |
229 unlink (file); | |
230 } | |
231 gl_list_iterator_free (&iter); | |
232 | |
233 /* Then cleanup the subdirectories. */ | |
234 iter = gl_list_iterator (dir->subdirs); | |
235 while (gl_list_iterator_next (&iter, &element, NULL)) | |
236 { | |
237 const char *subdir = (const char *) element; | |
238 rmdir (subdir); | |
239 } | |
240 gl_list_iterator_free (&iter); | |
241 | |
242 /* Then cleanup the temporary directory itself. */ | |
243 rmdir (dir->dirname); | |
244 } | |
245 } | |
246 } | |
247 | |
248 /* Create a temporary directory. | |
249 PREFIX is used as a prefix for the name of the temporary directory. It | |
250 should be short and still give an indication about the program. | |
251 PARENTDIR can be used to specify the parent directory; if NULL, a default | |
252 parent directory is used (either $TMPDIR or /tmp or similar). | |
253 CLEANUP_VERBOSE determines whether errors during explicit cleanup are | |
254 reported to standard error. | |
255 Return a fresh 'struct temp_dir' on success. Upon error, an error message | |
256 is shown and NULL is returned. */ | |
257 struct temp_dir * | |
258 create_temp_dir (const char *prefix, const char *parentdir, | |
259 bool cleanup_verbose) | |
260 { | |
261 struct tempdir * volatile *tmpdirp = NULL; | |
262 struct tempdir *tmpdir; | |
263 size_t i; | |
7586
4a8b5467d8b2
Make it compile in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
7513
diff
changeset
|
264 char *xtemplate; |
7044 | 265 char *tmpdirname; |
266 | |
267 /* See whether it can take the slot of an earlier temporary directory | |
268 already cleaned up. */ | |
269 for (i = 0; i < cleanup_list.tempdir_count; i++) | |
270 if (cleanup_list.tempdir_list[i] == NULL) | |
271 { | |
272 tmpdirp = &cleanup_list.tempdir_list[i]; | |
273 break; | |
274 } | |
275 if (tmpdirp == NULL) | |
276 { | |
277 /* See whether the array needs to be extended. */ | |
278 if (cleanup_list.tempdir_count == cleanup_list.tempdir_allocated) | |
279 { | |
280 /* Note that we cannot use xrealloc(), because then the cleanup() | |
281 function could access an already deallocated array. */ | |
282 struct tempdir * volatile *old_array = cleanup_list.tempdir_list; | |
283 size_t old_allocated = cleanup_list.tempdir_allocated; | |
284 size_t new_allocated = 2 * cleanup_list.tempdir_allocated + 1; | |
285 struct tempdir * volatile *new_array = | |
7603
23f14c284219
Simplify xmalloc expressions. Add overflow check in xmalloc arguments.
Bruno Haible <bruno@clisp.org>
parents:
7586
diff
changeset
|
286 XNMALLOC (new_allocated, struct tempdir * volatile); |
7044 | 287 |
288 if (old_allocated == 0) | |
289 /* First use of this facility. Register the cleanup handler. */ | |
290 at_fatal_signal (&cleanup); | |
291 else | |
292 { | |
293 /* Don't use memcpy() here, because memcpy takes non-volatile | |
294 arguments and is therefore not guaranteed to complete all | |
295 memory stores before the next statement. */ | |
296 size_t k; | |
297 | |
298 for (k = 0; k < old_allocated; k++) | |
299 new_array[k] = old_array[k]; | |
300 } | |
301 | |
302 cleanup_list.tempdir_list = new_array; | |
303 cleanup_list.tempdir_allocated = new_allocated; | |
304 | |
305 /* Now we can free the old array. */ | |
306 if (old_array != NULL) | |
307 free ((struct tempdir **) old_array); | |
308 } | |
309 | |
310 tmpdirp = &cleanup_list.tempdir_list[cleanup_list.tempdir_count]; | |
311 /* Initialize *tmpdirp before incrementing tempdir_count, so that | |
312 cleanup() will skip this entry before it is fully initialized. */ | |
313 *tmpdirp = NULL; | |
314 cleanup_list.tempdir_count++; | |
315 } | |
316 | |
317 /* Initialize a 'struct tempdir'. */ | |
7603
23f14c284219
Simplify xmalloc expressions. Add overflow check in xmalloc arguments.
Bruno Haible <bruno@clisp.org>
parents:
7586
diff
changeset
|
318 tmpdir = XMALLOC (struct tempdir); |
7044 | 319 tmpdir->dirname = NULL; |
320 tmpdir->cleanup_verbose = cleanup_verbose; | |
321 tmpdir->subdirs = gl_list_create_empty (GL_LINKEDHASH_LIST, | |
8438
238942284e2f
Allow the use of a destructor for the values stored in the list.
Bruno Haible <bruno@clisp.org>
parents:
8192
diff
changeset
|
322 string_equals, string_hash, NULL, |
238942284e2f
Allow the use of a destructor for the values stored in the list.
Bruno Haible <bruno@clisp.org>
parents:
8192
diff
changeset
|
323 false); |
7044 | 324 tmpdir->files = gl_list_create_empty (GL_LINKEDHASH_LIST, |
8438
238942284e2f
Allow the use of a destructor for the values stored in the list.
Bruno Haible <bruno@clisp.org>
parents:
8192
diff
changeset
|
325 string_equals, string_hash, NULL, |
238942284e2f
Allow the use of a destructor for the values stored in the list.
Bruno Haible <bruno@clisp.org>
parents:
8192
diff
changeset
|
326 false); |
7044 | 327 |
328 /* Create the temporary directory. */ | |
8948
a162347a0232
Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents:
8438
diff
changeset
|
329 xtemplate = (char *) xmalloca (PATH_MAX); |
7586
4a8b5467d8b2
Make it compile in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
7513
diff
changeset
|
330 if (path_search (xtemplate, PATH_MAX, parentdir, prefix, parentdir == NULL)) |
7044 | 331 { |
332 error (0, errno, | |
333 _("cannot find a temporary directory, try setting $TMPDIR")); | |
334 goto quit; | |
335 } | |
336 block_fatal_signals (); | |
7586
4a8b5467d8b2
Make it compile in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
7513
diff
changeset
|
337 tmpdirname = mkdtemp (xtemplate); |
7044 | 338 if (tmpdirname != NULL) |
339 { | |
340 tmpdir->dirname = tmpdirname; | |
341 *tmpdirp = tmpdir; | |
342 } | |
343 unblock_fatal_signals (); | |
344 if (tmpdirname == NULL) | |
345 { | |
346 error (0, errno, | |
347 _("cannot create a temporary directory using template \"%s\""), | |
7586
4a8b5467d8b2
Make it compile in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
7513
diff
changeset
|
348 xtemplate); |
7044 | 349 goto quit; |
350 } | |
351 /* Replace tmpdir->dirname with a copy that has indefinite extent. | |
352 We cannot do this inside the block_fatal_signals/unblock_fatal_signals | |
353 block because then the cleanup handler would not remove the directory | |
354 if xstrdup fails. */ | |
355 tmpdir->dirname = xstrdup (tmpdirname); | |
8948
a162347a0232
Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents:
8438
diff
changeset
|
356 freea (xtemplate); |
7044 | 357 return (struct temp_dir *) tmpdir; |
358 | |
359 quit: | |
8948
a162347a0232
Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents:
8438
diff
changeset
|
360 freea (xtemplate); |
7044 | 361 return NULL; |
362 } | |
363 | |
364 /* Register the given ABSOLUTE_FILE_NAME as being a file inside DIR, that | |
365 needs to be removed before DIR can be removed. | |
366 Should be called before the file ABSOLUTE_FILE_NAME is created. */ | |
367 void | |
368 register_temp_file (struct temp_dir *dir, | |
369 const char *absolute_file_name) | |
370 { | |
371 struct tempdir *tmpdir = (struct tempdir *)dir; | |
372 | |
373 /* Add absolute_file_name to tmpdir->files, without duplicates. */ | |
374 if (gl_list_search (tmpdir->files, absolute_file_name) == NULL) | |
375 gl_list_add_first (tmpdir->files, xstrdup (absolute_file_name)); | |
376 } | |
377 | |
378 /* Unregister the given ABSOLUTE_FILE_NAME as being a file inside DIR, that | |
379 needs to be removed before DIR can be removed. | |
380 Should be called when the file ABSOLUTE_FILE_NAME could not be created. */ | |
381 void | |
382 unregister_temp_file (struct temp_dir *dir, | |
383 const char *absolute_file_name) | |
384 { | |
385 struct tempdir *tmpdir = (struct tempdir *)dir; | |
386 gl_list_t list = tmpdir->files; | |
387 gl_list_node_t node; | |
388 | |
389 node = gl_list_search (list, absolute_file_name); | |
390 if (node != NULL) | |
391 { | |
392 char *old_string = (char *) gl_list_node_value (list, node); | |
393 | |
394 gl_list_remove_node (list, node); | |
395 free (old_string); | |
396 } | |
397 } | |
398 | |
399 /* Register the given ABSOLUTE_DIR_NAME as being a subdirectory inside DIR, | |
400 that needs to be removed before DIR can be removed. | |
401 Should be called before the subdirectory ABSOLUTE_DIR_NAME is created. */ | |
402 void | |
403 register_temp_subdir (struct temp_dir *dir, | |
404 const char *absolute_dir_name) | |
405 { | |
406 struct tempdir *tmpdir = (struct tempdir *)dir; | |
407 | |
408 /* Add absolute_dir_name to tmpdir->subdirs, without duplicates. */ | |
409 if (gl_list_search (tmpdir->subdirs, absolute_dir_name) == NULL) | |
410 gl_list_add_first (tmpdir->subdirs, xstrdup (absolute_dir_name)); | |
411 } | |
412 | |
413 /* Unregister the given ABSOLUTE_DIR_NAME as being a subdirectory inside DIR, | |
414 that needs to be removed before DIR can be removed. | |
415 Should be called when the subdirectory ABSOLUTE_DIR_NAME could not be | |
416 created. */ | |
417 void | |
418 unregister_temp_subdir (struct temp_dir *dir, | |
419 const char *absolute_dir_name) | |
420 { | |
421 struct tempdir *tmpdir = (struct tempdir *)dir; | |
422 gl_list_t list = tmpdir->subdirs; | |
423 gl_list_node_t node; | |
424 | |
425 node = gl_list_search (list, absolute_dir_name); | |
426 if (node != NULL) | |
427 { | |
428 char *old_string = (char *) gl_list_node_value (list, node); | |
429 | |
430 gl_list_remove_node (list, node); | |
431 free (old_string); | |
432 } | |
433 } | |
434 | |
7415 | 435 /* Remove a file, with optional error message. |
436 Return 0 upon success, or -1 if there was some problem. */ | |
437 static int | |
7044 | 438 do_unlink (struct temp_dir *dir, const char *absolute_file_name) |
439 { | |
440 if (unlink (absolute_file_name) < 0 && dir->cleanup_verbose | |
441 && errno != ENOENT) | |
7415 | 442 { |
443 error (0, errno, _("cannot remove temporary file %s"), absolute_file_name); | |
444 return -1; | |
445 } | |
446 return 0; | |
7044 | 447 } |
448 | |
7415 | 449 /* Remove a directory, with optional error message. |
450 Return 0 upon success, or -1 if there was some problem. */ | |
451 static int | |
7044 | 452 do_rmdir (struct temp_dir *dir, const char *absolute_dir_name) |
453 { | |
454 if (rmdir (absolute_dir_name) < 0 && dir->cleanup_verbose | |
455 && errno != ENOENT) | |
7415 | 456 { |
457 error (0, errno, | |
458 _("cannot remove temporary directory %s"), absolute_dir_name); | |
459 return -1; | |
460 } | |
461 return 0; | |
7044 | 462 } |
463 | |
7415 | 464 /* Remove the given ABSOLUTE_FILE_NAME and unregister it. |
465 Return 0 upon success, or -1 if there was some problem. */ | |
466 int | |
7044 | 467 cleanup_temp_file (struct temp_dir *dir, |
468 const char *absolute_file_name) | |
469 { | |
7415 | 470 int err; |
471 | |
472 err = do_unlink (dir, absolute_file_name); | |
7044 | 473 unregister_temp_file (dir, absolute_file_name); |
7415 | 474 |
475 return err; | |
7044 | 476 } |
477 | |
7415 | 478 /* Remove the given ABSOLUTE_DIR_NAME and unregister it. |
479 Return 0 upon success, or -1 if there was some problem. */ | |
480 int | |
7044 | 481 cleanup_temp_subdir (struct temp_dir *dir, |
482 const char *absolute_dir_name) | |
483 { | |
7415 | 484 int err; |
485 | |
486 err = do_rmdir (dir, absolute_dir_name); | |
7044 | 487 unregister_temp_subdir (dir, absolute_dir_name); |
7415 | 488 |
489 return err; | |
7044 | 490 } |
491 | |
7415 | 492 /* Remove all registered files and subdirectories inside DIR. |
493 Return 0 upon success, or -1 if there was some problem. */ | |
494 int | |
7044 | 495 cleanup_temp_dir_contents (struct temp_dir *dir) |
496 { | |
497 struct tempdir *tmpdir = (struct tempdir *)dir; | |
7415 | 498 int err = 0; |
7044 | 499 gl_list_t list; |
500 gl_list_iterator_t iter; | |
501 const void *element; | |
502 gl_list_node_t node; | |
503 | |
504 /* First cleanup the files in the subdirectories. */ | |
505 list = tmpdir->files; | |
506 iter = gl_list_iterator (list); | |
507 while (gl_list_iterator_next (&iter, &element, &node)) | |
508 { | |
509 char *file = (char *) element; | |
510 | |
7415 | 511 err |= do_unlink (dir, file); |
7044 | 512 gl_list_remove_node (list, node); |
513 /* Now only we can free file. */ | |
514 free (file); | |
515 } | |
516 gl_list_iterator_free (&iter); | |
517 | |
518 /* Then cleanup the subdirectories. */ | |
519 list = tmpdir->subdirs; | |
520 iter = gl_list_iterator (list); | |
521 while (gl_list_iterator_next (&iter, &element, &node)) | |
522 { | |
523 char *subdir = (char *) element; | |
524 | |
7415 | 525 err |= do_rmdir (dir, subdir); |
7044 | 526 gl_list_remove_node (list, node); |
527 /* Now only we can free subdir. */ | |
528 free (subdir); | |
529 } | |
530 gl_list_iterator_free (&iter); | |
7415 | 531 |
532 return err; | |
7044 | 533 } |
534 | |
535 /* Remove all registered files and subdirectories inside DIR and DIR itself. | |
7415 | 536 DIR cannot be used any more after this call. |
537 Return 0 upon success, or -1 if there was some problem. */ | |
538 int | |
7044 | 539 cleanup_temp_dir (struct temp_dir *dir) |
540 { | |
541 struct tempdir *tmpdir = (struct tempdir *)dir; | |
7415 | 542 int err = 0; |
7044 | 543 size_t i; |
544 | |
7415 | 545 err |= cleanup_temp_dir_contents (dir); |
546 err |= do_rmdir (dir, tmpdir->dirname); | |
7044 | 547 |
548 for (i = 0; i < cleanup_list.tempdir_count; i++) | |
549 if (cleanup_list.tempdir_list[i] == tmpdir) | |
550 { | |
551 /* Remove cleanup_list.tempdir_list[i]. */ | |
552 if (i + 1 == cleanup_list.tempdir_count) | |
553 { | |
554 while (i > 0 && cleanup_list.tempdir_list[i - 1] == NULL) | |
555 i--; | |
556 cleanup_list.tempdir_count = i; | |
557 } | |
558 else | |
559 cleanup_list.tempdir_list[i] = NULL; | |
560 /* Now only we can free the tmpdir->dirname and tmpdir itself. */ | |
561 free (tmpdir->dirname); | |
562 free (tmpdir); | |
7415 | 563 return err; |
7044 | 564 } |
565 | |
566 /* The user passed an invalid DIR argument. */ | |
567 abort (); | |
568 } | |
7411
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
569 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
570 |
8161
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
571 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
572 |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
573 /* On Windows, opening a file with _O_TEMPORARY has the effect of passing |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
574 the FILE_FLAG_DELETE_ON_CLOSE flag to CreateFile(), which has the effect |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
575 of deleting the file when it is closed - even when the program crashes. |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
576 But (according to the Cygwin sources) it works only on Windows NT or newer. |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
577 So we cache the info whether we are running on Windows NT or newer. */ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
578 |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
579 static bool |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
580 supports_delete_on_close () |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
581 { |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
582 static int known; /* 1 = yes, -1 = no, 0 = unknown */ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
583 if (!known) |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
584 { |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
585 OSVERSIONINFO v; |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
586 |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
587 if (GetVersionEx (&v)) |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
588 known = (v.dwPlatformId == VER_PLATFORM_WIN32_NT ? 1 : -1); |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
589 else |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
590 known = -1; |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
591 } |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
592 return (known > 0); |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
593 } |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
594 |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
595 #endif |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
596 |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
597 |
7411
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
598 /* Register a file descriptor to be closed. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
599 static void |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
600 register_fd (int fd) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
601 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
602 if (descriptors == NULL) |
8438
238942284e2f
Allow the use of a destructor for the values stored in the list.
Bruno Haible <bruno@clisp.org>
parents:
8192
diff
changeset
|
603 descriptors = gl_list_create_empty (GL_LINKEDHASH_LIST, NULL, NULL, NULL, |
238942284e2f
Allow the use of a destructor for the values stored in the list.
Bruno Haible <bruno@clisp.org>
parents:
8192
diff
changeset
|
604 false); |
7411
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
605 gl_list_add_first (descriptors, (void *) (uintptr_t) fd); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
606 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
607 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
608 /* Unregister a file descriptor to be closed. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
609 static void |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
610 unregister_fd (int fd) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
611 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
612 gl_list_t fds = descriptors; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
613 gl_list_node_t node; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
614 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
615 if (fds == NULL) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
616 /* descriptors should already contain fd. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
617 abort (); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
618 node = gl_list_search (fds, (void *) (uintptr_t) fd); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
619 if (node == NULL) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
620 /* descriptors should already contain fd. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
621 abort (); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
622 gl_list_remove_node (fds, node); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
623 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
624 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
625 /* Open a temporary file in a temporary directory. |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
626 Registers the resulting file descriptor to be closed. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
627 int |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
628 open_temp (const char *file_name, int flags, mode_t mode) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
629 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
630 int fd; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
631 int saved_errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
632 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
633 block_fatal_signals (); |
8161
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
634 /* Note: 'open' here is actually open() or open_safer(). */ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
635 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
636 /* Use _O_TEMPORARY when possible, to increase the chances that the |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
637 temporary file is removed when the process crashes. */ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
638 if (supports_delete_on_close ()) |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
639 fd = open (file_name, flags | _O_TEMPORARY, mode); |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
640 else |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
641 #endif |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
642 fd = open (file_name, flags, mode); |
7411
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
643 saved_errno = errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
644 if (fd >= 0) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
645 register_fd (fd); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
646 unblock_fatal_signals (); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
647 errno = saved_errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
648 return fd; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
649 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
650 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
651 /* Open a temporary file in a temporary directory. |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
652 Registers the resulting file descriptor to be closed. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
653 FILE * |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
654 fopen_temp (const char *file_name, const char *mode) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
655 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
656 FILE *fp; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
657 int saved_errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
658 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
659 block_fatal_signals (); |
8161
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
660 /* Note: 'fopen' here is actually fopen() or fopen_safer(). */ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
661 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
662 /* Use _O_TEMPORARY when possible, to increase the chances that the |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
663 temporary file is removed when the process crashes. */ |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
664 if (supports_delete_on_close ()) |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
665 { |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
666 size_t mode_len = strlen (mode); |
8948
a162347a0232
Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents:
8438
diff
changeset
|
667 char *augmented_mode = (char *) xmalloca (mode_len + 2); |
8161
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
668 memcpy (augmented_mode, mode, mode_len); |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
669 memcpy (augmented_mode + mode_len, "D", 2); |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
670 |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
671 fp = fopen (file_name, augmented_mode); |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
672 saved_errno = errno; |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
673 |
8948
a162347a0232
Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents:
8438
diff
changeset
|
674 freea (augmented_mode); |
8161
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
675 } |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
676 else |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
677 #endif |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
678 { |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
679 fp = fopen (file_name, mode); |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
680 saved_errno = errno; |
f7359fba603e
Make use of _O_TEMPORARY on native Woe32 platforms.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
681 } |
7411
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
682 if (fp != NULL) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
683 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
684 /* It is sufficient to register fileno (fp) instead of the entire fp, |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
685 because at cleanup time there is no need to do an fflush (fp); a |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
686 close (fileno (fp)) will be enough. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
687 int fd = fileno (fp); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
688 if (!(fd >= 0)) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
689 abort (); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
690 register_fd (fd); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
691 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
692 unblock_fatal_signals (); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
693 errno = saved_errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
694 return fp; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
695 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
696 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
697 /* Close a temporary file in a temporary directory. |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
698 Unregisters the previously registered file descriptor. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
699 int |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
700 close_temp (int fd) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
701 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
702 if (fd >= 0) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
703 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
704 /* No blocking of signals is needed here, since a double close of a |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
705 file descriptor is harmless. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
706 int result = close (fd); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
707 int saved_errno = errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
708 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
709 /* No race condition here: we assume a single-threaded program, hence |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
710 fd cannot be re-opened here. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
711 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
712 unregister_fd (fd); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
713 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
714 errno = saved_errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
715 return result; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
716 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
717 else |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
718 return close (fd); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
719 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
720 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
721 /* Close a temporary file in a temporary directory. |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
722 Unregisters the previously registered file descriptor. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
723 int |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
724 fclose_temp (FILE *fp) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
725 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
726 int fd = fileno (fp); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
727 /* No blocking of signals is needed here, since a double close of a |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
728 file descriptor is harmless. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
729 int result = fclose (fp); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
730 int saved_errno = errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
731 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
732 /* No race condition here: we assume a single-threaded program, hence |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
733 fd cannot be re-opened here. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
734 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
735 unregister_fd (fd); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
736 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
737 errno = saved_errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
738 return result; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
739 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
740 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
741 #if GNULIB_FWRITEERROR |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
742 /* Like fwriteerror. |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
743 Unregisters the previously registered file descriptor. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
744 int |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
745 fwriteerror_temp (FILE *fp) |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
746 { |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
747 int fd = fileno (fp); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
748 /* No blocking of signals is needed here, since a double close of a |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
749 file descriptor is harmless. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
750 int result = fwriteerror (fp); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
751 int saved_errno = errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
752 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
753 /* No race condition here: we assume a single-threaded program, hence |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
754 fd cannot be re-opened here. */ |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
755 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
756 unregister_fd (fd); |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
757 |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
758 errno = saved_errno; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
759 return result; |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
760 } |
67235cf9199a
Have clean-temp register file open descriptors to temporary files.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
761 #endif |
7417
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
762 |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
763 #if GNULIB_CLOSE_STREAM |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
764 /* Like close_stream. |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
765 Unregisters the previously registered file descriptor. */ |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
766 int |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
767 close_stream_temp (FILE *fp) |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
768 { |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
769 int fd = fileno (fp); |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
770 /* No blocking of signals is needed here, since a double close of a |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
771 file descriptor is harmless. */ |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
772 int result = close_stream (fp); |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
773 int saved_errno = errno; |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
774 |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
775 /* No race condition here: we assume a single-threaded program, hence |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
776 fd cannot be re-opened here. */ |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
777 |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
778 unregister_fd (fd); |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
779 |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
780 errno = saved_errno; |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
781 return result; |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
782 } |
fa9e9b096831
* clean-temp.h (close_stream_temp): New declaration.
Eric Blake <ebb9@byu.net>
parents:
7415
diff
changeset
|
783 #endif |