1 /* Temporary directories and temporary files with automatic cleanup.
2 Copyright (C) 2001, 2003, 2006 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2006.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
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.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include "clean-temp.h"
33 #include "fatal-signal.h"
39 #include "gl_linkedhash_list.h"
42 #define _(str) gettext (str)
45 # define uintptr_t unsigned long
49 /* The use of 'volatile' in the types below (and ISO C 99 section 5.1.2.3.(5))
50 ensure that while constructing or modifying the data structures, the field
51 values are written to memory in the order of the C statements. So the
52 signal handler can rely on these field values to be up to date. */
55 /* Registry for a single temporary directory.
56 'struct temp_dir' from the public header file overlaps with this. */
59 /* The absolute pathname of the directory. */
60 char * volatile dirname;
61 /* Whether errors during explicit cleanup are reported to standard error. */
63 /* Absolute pathnames of subdirectories. */
64 gl_list_t /* <char *> */ volatile subdirs;
65 /* Absolute pathnames of files. */
66 gl_list_t /* <char *> */ volatile files;
69 /* List of all temporary directories. */
72 struct tempdir * volatile * volatile tempdir_list;
73 size_t volatile tempdir_count;
74 size_t tempdir_allocated;
75 } cleanup_list /* = { NULL, 0, 0 } */;
77 /* List of all open file descriptors to temporary files. */
78 static gl_list_t /* <int> */ volatile descriptors;
81 /* For the subdirs and for the files, we use a gl_list_t of type LINKEDHASH.
82 Why? We need a data structure that
84 1) Can contain an arbitrary number of 'char *' values. The strings
85 are compared via strcmp, not pointer comparison.
86 2) Has insertion and deletion operations that are fast: ideally O(1),
87 or possibly O(log n). This is important for GNU sort, which may
88 create a large number of temporary files.
89 3) Allows iteration through all elements from within a signal handler.
90 4) May or may not allow duplicates. It doesn't matter here, since
91 any file or subdir can only be removed once.
93 Criterion 1) would allow any gl_list_t or gl_oset_t implementation.
95 Criterion 2) leaves only GL_LINKEDHASH_LIST, GL_TREEHASH_LIST, or
98 Criterion 3) puts at disadvantage GL_TREEHASH_LIST and GL_TREE_OSET.
99 Namely, iteration through the elements of a binary tree requires access
100 to many ->left, ->right, ->parent pointers. However, the rebalancing
101 code for insertion and deletion in an AVL or red-black tree is so
102 complicated that we cannot assume that >left, ->right, ->parent pointers
103 are in a consistent state throughout these operations. Therefore, to
104 avoid a crash in the signal handler, all destructive operations to the
105 lists would have to be protected by a
106 block_fatal_signals ();
108 unblock_fatal_signals ();
109 pair. Which causes extra system calls.
111 Criterion 3) would also discourage GL_ARRAY_LIST and GL_CARRAY_LIST,
112 if they were not already excluded. Namely, these implementations use
113 xrealloc(), leaving a time window in which in the list->elements pointer
114 points to already deallocated memory. To avoid a crash in the signal
115 handler at such a moment, all destructive operations would have to
116 protected by block/unblock_fatal_signals (), in this case too.
118 A list of type GL_LINKEDHASH_LIST without duplicates fulfills all
120 2) Insertion and deletion are O(1) on average.
121 3) The gl_list_iterator, gl_list_iterator_next implementations do
122 not trigger memory allocations, nor other system calls, and are
123 therefore safe to be called from a signal handler.
124 Furthermore, since SIGNAL_SAFE_LIST is defined, the implementation
125 of the destructive functions ensures that the list structure is
126 safe to be traversed at any moment, even when interrupted by an
130 /* String equality and hash code functions used by the lists. */
133 string_equals (const void *x1, const void *x2)
137 return strcmp (s1, s2) == 0;
140 #define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
142 /* A hash function for NUL-terminated char* strings using
143 the method described by Bruno Haible.
144 See http://www.haible.de/bruno/hashfunc.html. */
146 string_hash (const void *x)
152 h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
158 /* The signal handler. It gets called asynchronously. */
164 /* First close all file descriptors to temporary files. */
166 gl_list_t fds = descriptors;
170 gl_list_iterator_t iter;
173 iter = gl_list_iterator (fds);
174 while (gl_list_iterator_next (&iter, &element, NULL))
176 int fd = (int) (uintptr_t) element;
179 gl_list_iterator_free (&iter);
183 for (i = 0; i < cleanup_list.tempdir_count; i++)
185 struct tempdir *dir = cleanup_list.tempdir_list[i];
189 gl_list_iterator_t iter;
192 /* First cleanup the files in the subdirectories. */
193 iter = gl_list_iterator (dir->files);
194 while (gl_list_iterator_next (&iter, &element, NULL))
196 const char *file = (const char *) element;
199 gl_list_iterator_free (&iter);
201 /* Then cleanup the subdirectories. */
202 iter = gl_list_iterator (dir->subdirs);
203 while (gl_list_iterator_next (&iter, &element, NULL))
205 const char *subdir = (const char *) element;
208 gl_list_iterator_free (&iter);
210 /* Then cleanup the temporary directory itself. */
211 rmdir (dir->dirname);
216 /* Create a temporary directory.
217 PREFIX is used as a prefix for the name of the temporary directory. It
218 should be short and still give an indication about the program.
219 PARENTDIR can be used to specify the parent directory; if NULL, a default
220 parent directory is used (either $TMPDIR or /tmp or similar).
221 CLEANUP_VERBOSE determines whether errors during explicit cleanup are
222 reported to standard error.
223 Return a fresh 'struct temp_dir' on success. Upon error, an error message
224 is shown and NULL is returned. */
226 create_temp_dir (const char *prefix, const char *parentdir,
227 bool cleanup_verbose)
229 struct tempdir * volatile *tmpdirp = NULL;
230 struct tempdir *tmpdir;
235 /* See whether it can take the slot of an earlier temporary directory
236 already cleaned up. */
237 for (i = 0; i < cleanup_list.tempdir_count; i++)
238 if (cleanup_list.tempdir_list[i] == NULL)
240 tmpdirp = &cleanup_list.tempdir_list[i];
245 /* See whether the array needs to be extended. */
246 if (cleanup_list.tempdir_count == cleanup_list.tempdir_allocated)
248 /* Note that we cannot use xrealloc(), because then the cleanup()
249 function could access an already deallocated array. */
250 struct tempdir * volatile *old_array = cleanup_list.tempdir_list;
251 size_t old_allocated = cleanup_list.tempdir_allocated;
252 size_t new_allocated = 2 * cleanup_list.tempdir_allocated + 1;
253 struct tempdir * volatile *new_array =
254 (struct tempdir * volatile *)
255 xmalloc (new_allocated * sizeof (struct tempdir * volatile));
257 if (old_allocated == 0)
258 /* First use of this facility. Register the cleanup handler. */
259 at_fatal_signal (&cleanup);
262 /* Don't use memcpy() here, because memcpy takes non-volatile
263 arguments and is therefore not guaranteed to complete all
264 memory stores before the next statement. */
267 for (k = 0; k < old_allocated; k++)
268 new_array[k] = old_array[k];
271 cleanup_list.tempdir_list = new_array;
272 cleanup_list.tempdir_allocated = new_allocated;
274 /* Now we can free the old array. */
275 if (old_array != NULL)
276 free ((struct tempdir **) old_array);
279 tmpdirp = &cleanup_list.tempdir_list[cleanup_list.tempdir_count];
280 /* Initialize *tmpdirp before incrementing tempdir_count, so that
281 cleanup() will skip this entry before it is fully initialized. */
283 cleanup_list.tempdir_count++;
286 /* Initialize a 'struct tempdir'. */
287 tmpdir = (struct tempdir *) xmalloc (sizeof (struct tempdir));
288 tmpdir->dirname = NULL;
289 tmpdir->cleanup_verbose = cleanup_verbose;
290 tmpdir->subdirs = gl_list_create_empty (GL_LINKEDHASH_LIST,
291 string_equals, string_hash, false);
292 tmpdir->files = gl_list_create_empty (GL_LINKEDHASH_LIST,
293 string_equals, string_hash, false);
295 /* Create the temporary directory. */
296 template = (char *) xallocsa (PATH_MAX);
297 if (path_search (template, PATH_MAX, parentdir, prefix, parentdir == NULL))
300 _("cannot find a temporary directory, try setting $TMPDIR"));
303 block_fatal_signals ();
304 tmpdirname = mkdtemp (template);
305 if (tmpdirname != NULL)
307 tmpdir->dirname = tmpdirname;
310 unblock_fatal_signals ();
311 if (tmpdirname == NULL)
314 _("cannot create a temporary directory using template \"%s\""),
318 /* Replace tmpdir->dirname with a copy that has indefinite extent.
319 We cannot do this inside the block_fatal_signals/unblock_fatal_signals
320 block because then the cleanup handler would not remove the directory
322 tmpdir->dirname = xstrdup (tmpdirname);
324 return (struct temp_dir *) tmpdir;
331 /* Register the given ABSOLUTE_FILE_NAME as being a file inside DIR, that
332 needs to be removed before DIR can be removed.
333 Should be called before the file ABSOLUTE_FILE_NAME is created. */
335 register_temp_file (struct temp_dir *dir,
336 const char *absolute_file_name)
338 struct tempdir *tmpdir = (struct tempdir *)dir;
340 /* Add absolute_file_name to tmpdir->files, without duplicates. */
341 if (gl_list_search (tmpdir->files, absolute_file_name) == NULL)
342 gl_list_add_first (tmpdir->files, xstrdup (absolute_file_name));
345 /* Unregister the given ABSOLUTE_FILE_NAME as being a file inside DIR, that
346 needs to be removed before DIR can be removed.
347 Should be called when the file ABSOLUTE_FILE_NAME could not be created. */
349 unregister_temp_file (struct temp_dir *dir,
350 const char *absolute_file_name)
352 struct tempdir *tmpdir = (struct tempdir *)dir;
353 gl_list_t list = tmpdir->files;
356 node = gl_list_search (list, absolute_file_name);
359 char *old_string = (char *) gl_list_node_value (list, node);
361 gl_list_remove_node (list, node);
366 /* Register the given ABSOLUTE_DIR_NAME as being a subdirectory inside DIR,
367 that needs to be removed before DIR can be removed.
368 Should be called before the subdirectory ABSOLUTE_DIR_NAME is created. */
370 register_temp_subdir (struct temp_dir *dir,
371 const char *absolute_dir_name)
373 struct tempdir *tmpdir = (struct tempdir *)dir;
375 /* Add absolute_dir_name to tmpdir->subdirs, without duplicates. */
376 if (gl_list_search (tmpdir->subdirs, absolute_dir_name) == NULL)
377 gl_list_add_first (tmpdir->subdirs, xstrdup (absolute_dir_name));
380 /* Unregister the given ABSOLUTE_DIR_NAME as being a subdirectory inside DIR,
381 that needs to be removed before DIR can be removed.
382 Should be called when the subdirectory ABSOLUTE_DIR_NAME could not be
385 unregister_temp_subdir (struct temp_dir *dir,
386 const char *absolute_dir_name)
388 struct tempdir *tmpdir = (struct tempdir *)dir;
389 gl_list_t list = tmpdir->subdirs;
392 node = gl_list_search (list, absolute_dir_name);
395 char *old_string = (char *) gl_list_node_value (list, node);
397 gl_list_remove_node (list, node);
402 /* Remove a file, with optional error message. */
404 do_unlink (struct temp_dir *dir, const char *absolute_file_name)
406 if (unlink (absolute_file_name) < 0 && dir->cleanup_verbose
408 error (0, errno, _("cannot remove temporary file %s"), absolute_file_name);
411 /* Remove a directory, with optional error message. */
413 do_rmdir (struct temp_dir *dir, const char *absolute_dir_name)
415 if (rmdir (absolute_dir_name) < 0 && dir->cleanup_verbose
418 _("cannot remove temporary directory %s"), absolute_dir_name);
421 /* Remove the given ABSOLUTE_FILE_NAME and unregister it. */
423 cleanup_temp_file (struct temp_dir *dir,
424 const char *absolute_file_name)
426 do_unlink (dir, absolute_file_name);
427 unregister_temp_file (dir, absolute_file_name);
430 /* Remove the given ABSOLUTE_DIR_NAME and unregister it. */
432 cleanup_temp_subdir (struct temp_dir *dir,
433 const char *absolute_dir_name)
435 do_rmdir (dir, absolute_dir_name);
436 unregister_temp_subdir (dir, absolute_dir_name);
439 /* Remove all registered files and subdirectories inside DIR. */
441 cleanup_temp_dir_contents (struct temp_dir *dir)
443 struct tempdir *tmpdir = (struct tempdir *)dir;
445 gl_list_iterator_t iter;
449 /* First cleanup the files in the subdirectories. */
450 list = tmpdir->files;
451 iter = gl_list_iterator (list);
452 while (gl_list_iterator_next (&iter, &element, &node))
454 char *file = (char *) element;
456 do_unlink (dir, file);
457 gl_list_remove_node (list, node);
458 /* Now only we can free file. */
461 gl_list_iterator_free (&iter);
463 /* Then cleanup the subdirectories. */
464 list = tmpdir->subdirs;
465 iter = gl_list_iterator (list);
466 while (gl_list_iterator_next (&iter, &element, &node))
468 char *subdir = (char *) element;
470 do_rmdir (dir, subdir);
471 gl_list_remove_node (list, node);
472 /* Now only we can free subdir. */
475 gl_list_iterator_free (&iter);
478 /* Remove all registered files and subdirectories inside DIR and DIR itself.
479 DIR cannot be used any more after this call. */
481 cleanup_temp_dir (struct temp_dir *dir)
483 struct tempdir *tmpdir = (struct tempdir *)dir;
486 cleanup_temp_dir_contents (dir);
487 do_rmdir (dir, tmpdir->dirname);
489 for (i = 0; i < cleanup_list.tempdir_count; i++)
490 if (cleanup_list.tempdir_list[i] == tmpdir)
492 /* Remove cleanup_list.tempdir_list[i]. */
493 if (i + 1 == cleanup_list.tempdir_count)
495 while (i > 0 && cleanup_list.tempdir_list[i - 1] == NULL)
497 cleanup_list.tempdir_count = i;
500 cleanup_list.tempdir_list[i] = NULL;
501 /* Now only we can free the tmpdir->dirname and tmpdir itself. */
502 free (tmpdir->dirname);
507 /* The user passed an invalid DIR argument. */
512 /* Register a file descriptor to be closed. */
516 if (descriptors == NULL)
517 descriptors = gl_list_create_empty (GL_LINKEDHASH_LIST, NULL, NULL, false);
518 gl_list_add_first (descriptors, (void *) (uintptr_t) fd);
521 /* Unregister a file descriptor to be closed. */
523 unregister_fd (int fd)
525 gl_list_t fds = descriptors;
529 /* descriptors should already contain fd. */
531 node = gl_list_search (fds, (void *) (uintptr_t) fd);
533 /* descriptors should already contain fd. */
535 gl_list_remove_node (fds, node);
538 /* Open a temporary file in a temporary directory.
539 Registers the resulting file descriptor to be closed. */
541 open_temp (const char *file_name, int flags, mode_t mode)
546 block_fatal_signals ();
547 fd = open (file_name, flags, mode);
551 unblock_fatal_signals ();
556 /* Open a temporary file in a temporary directory.
557 Registers the resulting file descriptor to be closed. */
559 fopen_temp (const char *file_name, const char *mode)
564 block_fatal_signals ();
565 fp = fopen (file_name, mode);
569 /* It is sufficient to register fileno (fp) instead of the entire fp,
570 because at cleanup time there is no need to do an fflush (fp); a
571 close (fileno (fp)) will be enough. */
572 int fd = fileno (fp);
577 unblock_fatal_signals ();
582 /* Close a temporary file in a temporary directory.
583 Unregisters the previously registered file descriptor. */
589 /* No blocking of signals is needed here, since a double close of a
590 file descriptor is harmless. */
591 int result = close (fd);
592 int saved_errno = errno;
594 /* No race condition here: we assume a single-threaded program, hence
595 fd cannot be re-opened here. */
606 /* Close a temporary file in a temporary directory.
607 Unregisters the previously registered file descriptor. */
609 fclose_temp (FILE *fp)
611 int fd = fileno (fp);
612 /* No blocking of signals is needed here, since a double close of a
613 file descriptor is harmless. */
614 int result = fclose (fp);
615 int saved_errno = errno;
617 /* No race condition here: we assume a single-threaded program, hence
618 fd cannot be re-opened here. */
626 #if GNULIB_FWRITEERROR
628 Unregisters the previously registered file descriptor. */
630 fwriteerror_temp (FILE *fp)
632 int fd = fileno (fp);
633 /* No blocking of signals is needed here, since a double close of a
634 file descriptor is harmless. */
635 int result = fwriteerror (fp);
636 int saved_errno = errno;
638 /* No race condition here: we assume a single-threaded program, hence
639 fd cannot be re-opened here. */