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