Simplify xmalloc expressions. Add overflow check in xmalloc arguments.
[pspp] / 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             XNMALLOC (new_allocated, struct tempdir * volatile);
277
278           if (old_allocated == 0)
279             /* First use of this facility.  Register the cleanup handler.  */
280             at_fatal_signal (&cleanup);
281           else
282             {
283               /* Don't use memcpy() here, because memcpy takes non-volatile
284                  arguments and is therefore not guaranteed to complete all
285                  memory stores before the next statement.  */
286               size_t k;
287
288               for (k = 0; k < old_allocated; k++)
289                 new_array[k] = old_array[k];
290             }
291
292           cleanup_list.tempdir_list = new_array;
293           cleanup_list.tempdir_allocated = new_allocated;
294
295           /* Now we can free the old array.  */
296           if (old_array != NULL)
297             free ((struct tempdir **) old_array);
298         }
299
300       tmpdirp = &cleanup_list.tempdir_list[cleanup_list.tempdir_count];
301       /* Initialize *tmpdirp before incrementing tempdir_count, so that
302          cleanup() will skip this entry before it is fully initialized.  */
303       *tmpdirp = NULL;
304       cleanup_list.tempdir_count++;
305     }
306
307   /* Initialize a 'struct tempdir'.  */
308   tmpdir = XMALLOC (struct tempdir);
309   tmpdir->dirname = NULL;
310   tmpdir->cleanup_verbose = cleanup_verbose;
311   tmpdir->subdirs = gl_list_create_empty (GL_LINKEDHASH_LIST,
312                                           string_equals, string_hash, false);
313   tmpdir->files = gl_list_create_empty (GL_LINKEDHASH_LIST,
314                                         string_equals, string_hash, false);
315
316   /* Create the temporary directory.  */
317   xtemplate = (char *) xallocsa (PATH_MAX);
318   if (path_search (xtemplate, PATH_MAX, parentdir, prefix, parentdir == NULL))
319     {
320       error (0, errno,
321              _("cannot find a temporary directory, try setting $TMPDIR"));
322       goto quit;
323     }
324   block_fatal_signals ();
325   tmpdirname = mkdtemp (xtemplate);
326   if (tmpdirname != NULL)
327     {
328       tmpdir->dirname = tmpdirname;
329       *tmpdirp = tmpdir;
330     }
331   unblock_fatal_signals ();
332   if (tmpdirname == NULL)
333     {
334       error (0, errno,
335              _("cannot create a temporary directory using template \"%s\""),
336              xtemplate);
337       goto quit;
338     }
339   /* Replace tmpdir->dirname with a copy that has indefinite extent.
340      We cannot do this inside the block_fatal_signals/unblock_fatal_signals
341      block because then the cleanup handler would not remove the directory
342      if xstrdup fails.  */
343   tmpdir->dirname = xstrdup (tmpdirname);
344   freesa (xtemplate);
345   return (struct temp_dir *) tmpdir;
346
347  quit:
348   freesa (xtemplate);
349   return NULL;
350 }
351
352 /* Register the given ABSOLUTE_FILE_NAME as being a file inside DIR, that
353    needs to be removed before DIR can be removed.
354    Should be called before the file ABSOLUTE_FILE_NAME is created.  */
355 void
356 register_temp_file (struct temp_dir *dir,
357                     const char *absolute_file_name)
358 {
359   struct tempdir *tmpdir = (struct tempdir *)dir;
360
361   /* Add absolute_file_name to tmpdir->files, without duplicates.  */
362   if (gl_list_search (tmpdir->files, absolute_file_name) == NULL)
363     gl_list_add_first (tmpdir->files, xstrdup (absolute_file_name));
364 }
365
366 /* Unregister the given ABSOLUTE_FILE_NAME as being a file inside DIR, that
367    needs to be removed before DIR can be removed.
368    Should be called when the file ABSOLUTE_FILE_NAME could not be created.  */
369 void
370 unregister_temp_file (struct temp_dir *dir,
371                       const char *absolute_file_name)
372 {
373   struct tempdir *tmpdir = (struct tempdir *)dir;
374   gl_list_t list = tmpdir->files;
375   gl_list_node_t node;
376
377   node = gl_list_search (list, absolute_file_name);
378   if (node != NULL)
379     {
380       char *old_string = (char *) gl_list_node_value (list, node);
381
382       gl_list_remove_node (list, node);
383       free (old_string);
384     }
385 }
386
387 /* Register the given ABSOLUTE_DIR_NAME as being a subdirectory inside DIR,
388    that needs to be removed before DIR can be removed.
389    Should be called before the subdirectory ABSOLUTE_DIR_NAME is created.  */
390 void
391 register_temp_subdir (struct temp_dir *dir,
392                       const char *absolute_dir_name)
393 {
394   struct tempdir *tmpdir = (struct tempdir *)dir;
395
396   /* Add absolute_dir_name to tmpdir->subdirs, without duplicates.  */
397   if (gl_list_search (tmpdir->subdirs, absolute_dir_name) == NULL)
398     gl_list_add_first (tmpdir->subdirs, xstrdup (absolute_dir_name));
399 }
400
401 /* Unregister the given ABSOLUTE_DIR_NAME as being a subdirectory inside DIR,
402    that needs to be removed before DIR can be removed.
403    Should be called when the subdirectory ABSOLUTE_DIR_NAME could not be
404    created.  */
405 void
406 unregister_temp_subdir (struct temp_dir *dir,
407                         const char *absolute_dir_name)
408 {
409   struct tempdir *tmpdir = (struct tempdir *)dir;
410   gl_list_t list = tmpdir->subdirs;
411   gl_list_node_t node;
412
413   node = gl_list_search (list, absolute_dir_name);
414   if (node != NULL)
415     {
416       char *old_string = (char *) gl_list_node_value (list, node);
417
418       gl_list_remove_node (list, node);
419       free (old_string);
420     }
421 }
422
423 /* Remove a file, with optional error message.
424    Return 0 upon success, or -1 if there was some problem.  */
425 static int
426 do_unlink (struct temp_dir *dir, const char *absolute_file_name)
427 {
428   if (unlink (absolute_file_name) < 0 && dir->cleanup_verbose
429       && errno != ENOENT)
430     {
431       error (0, errno, _("cannot remove temporary file %s"), absolute_file_name);
432       return -1;
433     }
434   return 0;
435 }
436
437 /* Remove a directory, with optional error message.
438    Return 0 upon success, or -1 if there was some problem.  */
439 static int
440 do_rmdir (struct temp_dir *dir, const char *absolute_dir_name)
441 {
442   if (rmdir (absolute_dir_name) < 0 && dir->cleanup_verbose
443       && errno != ENOENT)
444     {
445       error (0, errno,
446              _("cannot remove temporary directory %s"), absolute_dir_name);
447       return -1;
448     }
449   return 0;
450 }
451
452 /* Remove the given ABSOLUTE_FILE_NAME and unregister it.
453    Return 0 upon success, or -1 if there was some problem.  */
454 int
455 cleanup_temp_file (struct temp_dir *dir,
456                    const char *absolute_file_name)
457 {
458   int err;
459
460   err = do_unlink (dir, absolute_file_name);
461   unregister_temp_file (dir, absolute_file_name);
462
463   return err;
464 }
465
466 /* Remove the given ABSOLUTE_DIR_NAME and unregister it.
467    Return 0 upon success, or -1 if there was some problem.  */
468 int
469 cleanup_temp_subdir (struct temp_dir *dir,
470                      const char *absolute_dir_name)
471 {
472   int err;
473
474   err = do_rmdir (dir, absolute_dir_name);
475   unregister_temp_subdir (dir, absolute_dir_name);
476
477   return err;
478 }
479
480 /* Remove all registered files and subdirectories inside DIR.
481    Return 0 upon success, or -1 if there was some problem.  */
482 int
483 cleanup_temp_dir_contents (struct temp_dir *dir)
484 {
485   struct tempdir *tmpdir = (struct tempdir *)dir;
486   int err = 0;
487   gl_list_t list;
488   gl_list_iterator_t iter;
489   const void *element;
490   gl_list_node_t node;
491
492   /* First cleanup the files in the subdirectories.  */
493   list = tmpdir->files;
494   iter = gl_list_iterator (list);
495   while (gl_list_iterator_next (&iter, &element, &node))
496     {
497       char *file = (char *) element;
498
499       err |= do_unlink (dir, file);
500       gl_list_remove_node (list, node);
501       /* Now only we can free file.  */
502       free (file);
503     }
504   gl_list_iterator_free (&iter);
505
506   /* Then cleanup the subdirectories.  */
507   list = tmpdir->subdirs;
508   iter = gl_list_iterator (list);
509   while (gl_list_iterator_next (&iter, &element, &node))
510     {
511       char *subdir = (char *) element;
512
513       err |= do_rmdir (dir, subdir);
514       gl_list_remove_node (list, node);
515       /* Now only we can free subdir.  */
516       free (subdir);
517     }
518   gl_list_iterator_free (&iter);
519
520   return err;
521 }
522
523 /* Remove all registered files and subdirectories inside DIR and DIR itself.
524    DIR cannot be used any more after this call.
525    Return 0 upon success, or -1 if there was some problem.  */
526 int
527 cleanup_temp_dir (struct temp_dir *dir)
528 {
529   struct tempdir *tmpdir = (struct tempdir *)dir;
530   int err = 0;
531   size_t i;
532
533   err |= cleanup_temp_dir_contents (dir);
534   err |= do_rmdir (dir, tmpdir->dirname);
535
536   for (i = 0; i < cleanup_list.tempdir_count; i++)
537     if (cleanup_list.tempdir_list[i] == tmpdir)
538       {
539         /* Remove cleanup_list.tempdir_list[i].  */
540         if (i + 1 == cleanup_list.tempdir_count)
541           {
542             while (i > 0 && cleanup_list.tempdir_list[i - 1] == NULL)
543               i--;
544             cleanup_list.tempdir_count = i;
545           }
546         else
547           cleanup_list.tempdir_list[i] = NULL;
548         /* Now only we can free the tmpdir->dirname and tmpdir itself.  */
549         free (tmpdir->dirname);
550         free (tmpdir);
551         return err;
552       }
553
554   /* The user passed an invalid DIR argument.  */
555   abort ();
556 }
557
558
559 /* Register a file descriptor to be closed.  */
560 static void
561 register_fd (int fd)
562 {
563   if (descriptors == NULL)
564     descriptors = gl_list_create_empty (GL_LINKEDHASH_LIST, NULL, NULL, false);
565   gl_list_add_first (descriptors, (void *) (uintptr_t) fd);
566 }
567
568 /* Unregister a file descriptor to be closed.  */
569 static void
570 unregister_fd (int fd)
571 {
572   gl_list_t fds = descriptors;
573   gl_list_node_t node;
574
575   if (fds == NULL)
576     /* descriptors should already contain fd.  */
577     abort ();
578   node = gl_list_search (fds, (void *) (uintptr_t) fd);
579   if (node == NULL)
580     /* descriptors should already contain fd.  */
581     abort ();
582   gl_list_remove_node (fds, node);
583 }
584
585 /* Open a temporary file in a temporary directory.
586    Registers the resulting file descriptor to be closed.  */
587 int
588 open_temp (const char *file_name, int flags, mode_t mode)
589 {
590   int fd;
591   int saved_errno;
592
593   block_fatal_signals ();
594   fd = open (file_name, flags, mode); /* actually open or open_safer */
595   saved_errno = errno;
596   if (fd >= 0)
597     register_fd (fd);
598   unblock_fatal_signals ();
599   errno = saved_errno;
600   return fd;
601 }
602
603 /* Open a temporary file in a temporary directory.
604    Registers the resulting file descriptor to be closed.  */
605 FILE *
606 fopen_temp (const char *file_name, const char *mode)
607 {
608   FILE *fp;
609   int saved_errno;
610
611   block_fatal_signals ();
612   fp = fopen (file_name, mode); /* actually fopen or fopen_safer */
613   saved_errno = errno;
614   if (fp != NULL)
615     {
616       /* It is sufficient to register fileno (fp) instead of the entire fp,
617          because at cleanup time there is no need to do an fflush (fp); a
618          close (fileno (fp)) will be enough.  */
619       int fd = fileno (fp);
620       if (!(fd >= 0))
621         abort ();
622       register_fd (fd);
623     }
624   unblock_fatal_signals ();
625   errno = saved_errno;
626   return fp;
627 }
628
629 /* Close a temporary file in a temporary directory.
630    Unregisters the previously registered file descriptor.  */
631 int
632 close_temp (int fd)
633 {
634   if (fd >= 0)
635     {
636       /* No blocking of signals is needed here, since a double close of a
637          file descriptor is harmless.  */
638       int result = close (fd);
639       int saved_errno = errno;
640
641       /* No race condition here: we assume a single-threaded program, hence
642          fd cannot be re-opened here.  */
643
644       unregister_fd (fd);
645
646       errno = saved_errno;
647       return result;
648     }
649   else
650     return close (fd);
651 }
652
653 /* Close a temporary file in a temporary directory.
654    Unregisters the previously registered file descriptor.  */
655 int
656 fclose_temp (FILE *fp)
657 {
658   int fd = fileno (fp);
659   /* No blocking of signals is needed here, since a double close of a
660      file descriptor is harmless.  */
661   int result = fclose (fp);
662   int saved_errno = errno;
663
664   /* No race condition here: we assume a single-threaded program, hence
665      fd cannot be re-opened here.  */
666
667   unregister_fd (fd);
668
669   errno = saved_errno;
670   return result;
671 }
672
673 #if GNULIB_FWRITEERROR
674 /* Like fwriteerror.
675    Unregisters the previously registered file descriptor.  */
676 int
677 fwriteerror_temp (FILE *fp)
678 {
679   int fd = fileno (fp);
680   /* No blocking of signals is needed here, since a double close of a
681      file descriptor is harmless.  */
682   int result = fwriteerror (fp);
683   int saved_errno = errno;
684
685   /* No race condition here: we assume a single-threaded program, hence
686      fd cannot be re-opened here.  */
687
688   unregister_fd (fd);
689
690   errno = saved_errno;
691   return result;
692 }
693 #endif
694
695 #if GNULIB_CLOSE_STREAM
696 /* Like close_stream.
697    Unregisters the previously registered file descriptor.  */
698 int
699 close_stream_temp (FILE *fp)
700 {
701   int fd = fileno (fp);
702   /* No blocking of signals is needed here, since a double close of a
703      file descriptor is harmless.  */
704   int result = close_stream (fp);
705   int saved_errno = errno;
706
707   /* No race condition here: we assume a single-threaded program, hence
708      fd cannot be re-opened here.  */
709
710   unregister_fd (fd);
711
712   errno = saved_errno;
713   return result;
714 }
715 #endif