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"
34 #include "fatal-signal.h"
40 #include "gl_linkedhash_list.h"
42 #if GNULIB_FWRITEERROR
43 # include "fwriteerror.h"
45 #if GNULIB_CLOSE_STREAM
46 # include "close-stream.h"
48 #if GNULIB_FCNTL_SAFER
51 #if GNULIB_FOPEN_SAFER
55 #define _(str) gettext (str)
57 /* GNU Hurd doesn't have PATH_MAX. */
60 # define PATH_MAX MAXPATHLEN
62 # define PATH_MAX 1024
67 # define uintptr_t unsigned long
70 #if !GNULIB_FCNTL_SAFER
71 /* The results of open() in this file are not used with fchdir,
72 therefore save some unnecessary work in fchdir.c. */
78 /* The use of 'volatile' in the types below (and ISO C 99 section 5.1.2.3.(5))
79 ensure that while constructing or modifying the data structures, the field
80 values are written to memory in the order of the C statements. So the
81 signal handler can rely on these field values to be up to date. */
84 /* Registry for a single temporary directory.
85 'struct temp_dir' from the public header file overlaps with this. */
88 /* The absolute pathname of the directory. */
89 char * volatile dirname;
90 /* Whether errors during explicit cleanup are reported to standard error. */
92 /* Absolute pathnames of subdirectories. */
93 gl_list_t /* <char *> */ volatile subdirs;
94 /* Absolute pathnames of files. */
95 gl_list_t /* <char *> */ volatile files;
98 /* List of all temporary directories. */
101 struct tempdir * volatile * volatile tempdir_list;
102 size_t volatile tempdir_count;
103 size_t tempdir_allocated;
104 } cleanup_list /* = { NULL, 0, 0 } */;
106 /* List of all open file descriptors to temporary files. */
107 static gl_list_t /* <int> */ volatile descriptors;
110 /* For the subdirs and for the files, we use a gl_list_t of type LINKEDHASH.
111 Why? We need a data structure that
113 1) Can contain an arbitrary number of 'char *' values. The strings
114 are compared via strcmp, not pointer comparison.
115 2) Has insertion and deletion operations that are fast: ideally O(1),
116 or possibly O(log n). This is important for GNU sort, which may
117 create a large number of temporary files.
118 3) Allows iteration through all elements from within a signal handler.
119 4) May or may not allow duplicates. It doesn't matter here, since
120 any file or subdir can only be removed once.
122 Criterion 1) would allow any gl_list_t or gl_oset_t implementation.
124 Criterion 2) leaves only GL_LINKEDHASH_LIST, GL_TREEHASH_LIST, or
127 Criterion 3) puts at disadvantage GL_TREEHASH_LIST and GL_TREE_OSET.
128 Namely, iteration through the elements of a binary tree requires access
129 to many ->left, ->right, ->parent pointers. However, the rebalancing
130 code for insertion and deletion in an AVL or red-black tree is so
131 complicated that we cannot assume that >left, ->right, ->parent pointers
132 are in a consistent state throughout these operations. Therefore, to
133 avoid a crash in the signal handler, all destructive operations to the
134 lists would have to be protected by a
135 block_fatal_signals ();
137 unblock_fatal_signals ();
138 pair. Which causes extra system calls.
140 Criterion 3) would also discourage GL_ARRAY_LIST and GL_CARRAY_LIST,
141 if they were not already excluded. Namely, these implementations use
142 xrealloc(), leaving a time window in which in the list->elements pointer
143 points to already deallocated memory. To avoid a crash in the signal
144 handler at such a moment, all destructive operations would have to
145 protected by block/unblock_fatal_signals (), in this case too.
147 A list of type GL_LINKEDHASH_LIST without duplicates fulfills all
149 2) Insertion and deletion are O(1) on average.
150 3) The gl_list_iterator, gl_list_iterator_next implementations do
151 not trigger memory allocations, nor other system calls, and are
152 therefore safe to be called from a signal handler.
153 Furthermore, since SIGNAL_SAFE_LIST is defined, the implementation
154 of the destructive functions ensures that the list structure is
155 safe to be traversed at any moment, even when interrupted by an
159 /* String equality and hash code functions used by the lists. */
162 string_equals (const void *x1, const void *x2)
164 const char *s1 = (const char *) x1;
165 const char *s2 = (const char *) x2;
166 return strcmp (s1, s2) == 0;
169 #define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
171 /* A hash function for NUL-terminated char* strings using
172 the method described by Bruno Haible.
173 See http://www.haible.de/bruno/hashfunc.html. */
175 string_hash (const void *x)
177 const char *s = (const char *) x;
181 h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
187 /* The signal handler. It gets called asynchronously. */
193 /* First close all file descriptors to temporary files. */
195 gl_list_t fds = descriptors;
199 gl_list_iterator_t iter;
202 iter = gl_list_iterator (fds);
203 while (gl_list_iterator_next (&iter, &element, NULL))
205 int fd = (int) (uintptr_t) element;
208 gl_list_iterator_free (&iter);
212 for (i = 0; i < cleanup_list.tempdir_count; i++)
214 struct tempdir *dir = cleanup_list.tempdir_list[i];
218 gl_list_iterator_t iter;
221 /* First cleanup the files in the subdirectories. */
222 iter = gl_list_iterator (dir->files);
223 while (gl_list_iterator_next (&iter, &element, NULL))
225 const char *file = (const char *) element;
228 gl_list_iterator_free (&iter);
230 /* Then cleanup the subdirectories. */
231 iter = gl_list_iterator (dir->subdirs);
232 while (gl_list_iterator_next (&iter, &element, NULL))
234 const char *subdir = (const char *) element;
237 gl_list_iterator_free (&iter);
239 /* Then cleanup the temporary directory itself. */
240 rmdir (dir->dirname);
245 /* Create a temporary directory.
246 PREFIX is used as a prefix for the name of the temporary directory. It
247 should be short and still give an indication about the program.
248 PARENTDIR can be used to specify the parent directory; if NULL, a default
249 parent directory is used (either $TMPDIR or /tmp or similar).
250 CLEANUP_VERBOSE determines whether errors during explicit cleanup are
251 reported to standard error.
252 Return a fresh 'struct temp_dir' on success. Upon error, an error message
253 is shown and NULL is returned. */
255 create_temp_dir (const char *prefix, const char *parentdir,
256 bool cleanup_verbose)
258 struct tempdir * volatile *tmpdirp = NULL;
259 struct tempdir *tmpdir;
264 /* See whether it can take the slot of an earlier temporary directory
265 already cleaned up. */
266 for (i = 0; i < cleanup_list.tempdir_count; i++)
267 if (cleanup_list.tempdir_list[i] == NULL)
269 tmpdirp = &cleanup_list.tempdir_list[i];
274 /* See whether the array needs to be extended. */
275 if (cleanup_list.tempdir_count == cleanup_list.tempdir_allocated)
277 /* Note that we cannot use xrealloc(), because then the cleanup()
278 function could access an already deallocated array. */
279 struct tempdir * volatile *old_array = cleanup_list.tempdir_list;
280 size_t old_allocated = cleanup_list.tempdir_allocated;
281 size_t new_allocated = 2 * cleanup_list.tempdir_allocated + 1;
282 struct tempdir * volatile *new_array =
283 XNMALLOC (new_allocated, struct tempdir * volatile);
285 if (old_allocated == 0)
286 /* First use of this facility. Register the cleanup handler. */
287 at_fatal_signal (&cleanup);
290 /* Don't use memcpy() here, because memcpy takes non-volatile
291 arguments and is therefore not guaranteed to complete all
292 memory stores before the next statement. */
295 for (k = 0; k < old_allocated; k++)
296 new_array[k] = old_array[k];
299 cleanup_list.tempdir_list = new_array;
300 cleanup_list.tempdir_allocated = new_allocated;
302 /* Now we can free the old array. */
303 if (old_array != NULL)
304 free ((struct tempdir **) old_array);
307 tmpdirp = &cleanup_list.tempdir_list[cleanup_list.tempdir_count];
308 /* Initialize *tmpdirp before incrementing tempdir_count, so that
309 cleanup() will skip this entry before it is fully initialized. */
311 cleanup_list.tempdir_count++;
314 /* Initialize a 'struct tempdir'. */
315 tmpdir = XMALLOC (struct tempdir);
316 tmpdir->dirname = NULL;
317 tmpdir->cleanup_verbose = cleanup_verbose;
318 tmpdir->subdirs = gl_list_create_empty (GL_LINKEDHASH_LIST,
319 string_equals, string_hash, false);
320 tmpdir->files = gl_list_create_empty (GL_LINKEDHASH_LIST,
321 string_equals, string_hash, false);
323 /* Create the temporary directory. */
324 xtemplate = (char *) xallocsa (PATH_MAX);
325 if (path_search (xtemplate, PATH_MAX, parentdir, prefix, parentdir == NULL))
328 _("cannot find a temporary directory, try setting $TMPDIR"));
331 block_fatal_signals ();
332 tmpdirname = mkdtemp (xtemplate);
333 if (tmpdirname != NULL)
335 tmpdir->dirname = tmpdirname;
338 unblock_fatal_signals ();
339 if (tmpdirname == NULL)
342 _("cannot create a temporary directory using template \"%s\""),
346 /* Replace tmpdir->dirname with a copy that has indefinite extent.
347 We cannot do this inside the block_fatal_signals/unblock_fatal_signals
348 block because then the cleanup handler would not remove the directory
350 tmpdir->dirname = xstrdup (tmpdirname);
352 return (struct temp_dir *) tmpdir;
359 /* Register the given ABSOLUTE_FILE_NAME as being a file inside DIR, that
360 needs to be removed before DIR can be removed.
361 Should be called before the file ABSOLUTE_FILE_NAME is created. */
363 register_temp_file (struct temp_dir *dir,
364 const char *absolute_file_name)
366 struct tempdir *tmpdir = (struct tempdir *)dir;
368 /* Add absolute_file_name to tmpdir->files, without duplicates. */
369 if (gl_list_search (tmpdir->files, absolute_file_name) == NULL)
370 gl_list_add_first (tmpdir->files, xstrdup (absolute_file_name));
373 /* Unregister the given ABSOLUTE_FILE_NAME as being a file inside DIR, that
374 needs to be removed before DIR can be removed.
375 Should be called when the file ABSOLUTE_FILE_NAME could not be created. */
377 unregister_temp_file (struct temp_dir *dir,
378 const char *absolute_file_name)
380 struct tempdir *tmpdir = (struct tempdir *)dir;
381 gl_list_t list = tmpdir->files;
384 node = gl_list_search (list, absolute_file_name);
387 char *old_string = (char *) gl_list_node_value (list, node);
389 gl_list_remove_node (list, node);
394 /* Register the given ABSOLUTE_DIR_NAME as being a subdirectory inside DIR,
395 that needs to be removed before DIR can be removed.
396 Should be called before the subdirectory ABSOLUTE_DIR_NAME is created. */
398 register_temp_subdir (struct temp_dir *dir,
399 const char *absolute_dir_name)
401 struct tempdir *tmpdir = (struct tempdir *)dir;
403 /* Add absolute_dir_name to tmpdir->subdirs, without duplicates. */
404 if (gl_list_search (tmpdir->subdirs, absolute_dir_name) == NULL)
405 gl_list_add_first (tmpdir->subdirs, xstrdup (absolute_dir_name));
408 /* Unregister the given ABSOLUTE_DIR_NAME as being a subdirectory inside DIR,
409 that needs to be removed before DIR can be removed.
410 Should be called when the subdirectory ABSOLUTE_DIR_NAME could not be
413 unregister_temp_subdir (struct temp_dir *dir,
414 const char *absolute_dir_name)
416 struct tempdir *tmpdir = (struct tempdir *)dir;
417 gl_list_t list = tmpdir->subdirs;
420 node = gl_list_search (list, absolute_dir_name);
423 char *old_string = (char *) gl_list_node_value (list, node);
425 gl_list_remove_node (list, node);
430 /* Remove a file, with optional error message.
431 Return 0 upon success, or -1 if there was some problem. */
433 do_unlink (struct temp_dir *dir, const char *absolute_file_name)
435 if (unlink (absolute_file_name) < 0 && dir->cleanup_verbose
438 error (0, errno, _("cannot remove temporary file %s"), absolute_file_name);
444 /* Remove a directory, with optional error message.
445 Return 0 upon success, or -1 if there was some problem. */
447 do_rmdir (struct temp_dir *dir, const char *absolute_dir_name)
449 if (rmdir (absolute_dir_name) < 0 && dir->cleanup_verbose
453 _("cannot remove temporary directory %s"), absolute_dir_name);
459 /* Remove the given ABSOLUTE_FILE_NAME and unregister it.
460 Return 0 upon success, or -1 if there was some problem. */
462 cleanup_temp_file (struct temp_dir *dir,
463 const char *absolute_file_name)
467 err = do_unlink (dir, absolute_file_name);
468 unregister_temp_file (dir, absolute_file_name);
473 /* Remove the given ABSOLUTE_DIR_NAME and unregister it.
474 Return 0 upon success, or -1 if there was some problem. */
476 cleanup_temp_subdir (struct temp_dir *dir,
477 const char *absolute_dir_name)
481 err = do_rmdir (dir, absolute_dir_name);
482 unregister_temp_subdir (dir, absolute_dir_name);
487 /* Remove all registered files and subdirectories inside DIR.
488 Return 0 upon success, or -1 if there was some problem. */
490 cleanup_temp_dir_contents (struct temp_dir *dir)
492 struct tempdir *tmpdir = (struct tempdir *)dir;
495 gl_list_iterator_t iter;
499 /* First cleanup the files in the subdirectories. */
500 list = tmpdir->files;
501 iter = gl_list_iterator (list);
502 while (gl_list_iterator_next (&iter, &element, &node))
504 char *file = (char *) element;
506 err |= do_unlink (dir, file);
507 gl_list_remove_node (list, node);
508 /* Now only we can free file. */
511 gl_list_iterator_free (&iter);
513 /* Then cleanup the subdirectories. */
514 list = tmpdir->subdirs;
515 iter = gl_list_iterator (list);
516 while (gl_list_iterator_next (&iter, &element, &node))
518 char *subdir = (char *) element;
520 err |= do_rmdir (dir, subdir);
521 gl_list_remove_node (list, node);
522 /* Now only we can free subdir. */
525 gl_list_iterator_free (&iter);
530 /* Remove all registered files and subdirectories inside DIR and DIR itself.
531 DIR cannot be used any more after this call.
532 Return 0 upon success, or -1 if there was some problem. */
534 cleanup_temp_dir (struct temp_dir *dir)
536 struct tempdir *tmpdir = (struct tempdir *)dir;
540 err |= cleanup_temp_dir_contents (dir);
541 err |= do_rmdir (dir, tmpdir->dirname);
543 for (i = 0; i < cleanup_list.tempdir_count; i++)
544 if (cleanup_list.tempdir_list[i] == tmpdir)
546 /* Remove cleanup_list.tempdir_list[i]. */
547 if (i + 1 == cleanup_list.tempdir_count)
549 while (i > 0 && cleanup_list.tempdir_list[i - 1] == NULL)
551 cleanup_list.tempdir_count = i;
554 cleanup_list.tempdir_list[i] = NULL;
555 /* Now only we can free the tmpdir->dirname and tmpdir itself. */
556 free (tmpdir->dirname);
561 /* The user passed an invalid DIR argument. */
566 /* Register a file descriptor to be closed. */
570 if (descriptors == NULL)
571 descriptors = gl_list_create_empty (GL_LINKEDHASH_LIST, NULL, NULL, false);
572 gl_list_add_first (descriptors, (void *) (uintptr_t) fd);
575 /* Unregister a file descriptor to be closed. */
577 unregister_fd (int fd)
579 gl_list_t fds = descriptors;
583 /* descriptors should already contain fd. */
585 node = gl_list_search (fds, (void *) (uintptr_t) fd);
587 /* descriptors should already contain fd. */
589 gl_list_remove_node (fds, node);
592 /* Open a temporary file in a temporary directory.
593 Registers the resulting file descriptor to be closed. */
595 open_temp (const char *file_name, int flags, mode_t mode)
600 block_fatal_signals ();
601 fd = open (file_name, flags, mode); /* actually open or open_safer */
605 unblock_fatal_signals ();
610 /* Open a temporary file in a temporary directory.
611 Registers the resulting file descriptor to be closed. */
613 fopen_temp (const char *file_name, const char *mode)
618 block_fatal_signals ();
619 fp = fopen (file_name, mode); /* actually fopen or fopen_safer */
623 /* It is sufficient to register fileno (fp) instead of the entire fp,
624 because at cleanup time there is no need to do an fflush (fp); a
625 close (fileno (fp)) will be enough. */
626 int fd = fileno (fp);
631 unblock_fatal_signals ();
636 /* Close a temporary file in a temporary directory.
637 Unregisters the previously registered file descriptor. */
643 /* No blocking of signals is needed here, since a double close of a
644 file descriptor is harmless. */
645 int result = close (fd);
646 int saved_errno = errno;
648 /* No race condition here: we assume a single-threaded program, hence
649 fd cannot be re-opened here. */
660 /* Close a temporary file in a temporary directory.
661 Unregisters the previously registered file descriptor. */
663 fclose_temp (FILE *fp)
665 int fd = fileno (fp);
666 /* No blocking of signals is needed here, since a double close of a
667 file descriptor is harmless. */
668 int result = fclose (fp);
669 int saved_errno = errno;
671 /* No race condition here: we assume a single-threaded program, hence
672 fd cannot be re-opened here. */
680 #if GNULIB_FWRITEERROR
682 Unregisters the previously registered file descriptor. */
684 fwriteerror_temp (FILE *fp)
686 int fd = fileno (fp);
687 /* No blocking of signals is needed here, since a double close of a
688 file descriptor is harmless. */
689 int result = fwriteerror (fp);
690 int saved_errno = errno;
692 /* No race condition here: we assume a single-threaded program, hence
693 fd cannot be re-opened here. */
702 #if GNULIB_CLOSE_STREAM
703 /* Like close_stream.
704 Unregisters the previously registered file descriptor. */
706 close_stream_temp (FILE *fp)
708 int fd = fileno (fp);
709 /* No blocking of signals is needed here, since a double close of a
710 file descriptor is harmless. */
711 int result = close_stream (fp);
712 int saved_errno = errno;
714 /* No race condition here: we assume a single-threaded program, hence
715 fd cannot be re-opened here. */