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