From 228b83840e3f053aecfa9feac395fb6855adf044 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Fri, 1 Jul 2011 18:20:42 +0200 Subject: [PATCH] Fix bugs deleting temporary files and their containing directory. The clean_temp module provided by gnulib doesn't cleanup on program exit. We must do that ourselves. Secondly, the close_temp_file function was supposed to remove the file, but didn't do that. Thirdly, files were not being registered with the clean_temp module on creation. This change fixes these problems. --- src/libpspp/ext-array.c | 2 +- src/libpspp/temp-file.c | 53 +++++++++++++++++++++++++++++++++++------ tests/automake.mk | 17 +++++++++++++ 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/libpspp/ext-array.c b/src/libpspp/ext-array.c index 68bbe954f3..57ff8e4a7d 100644 --- a/src/libpspp/ext-array.c +++ b/src/libpspp/ext-array.c @@ -69,7 +69,7 @@ ext_array_destroy (struct ext_array *ea) { ok = !ext_array_error (ea); if (ea->file != NULL) - fclose (ea->file); + close_temp_file (ea->file); free (ea); } return ok; diff --git a/src/libpspp/temp-file.c b/src/libpspp/temp-file.c index ffd5da7cef..0391ec9c01 100644 --- a/src/libpspp/temp-file.c +++ b/src/libpspp/temp-file.c @@ -19,6 +19,8 @@ #include #include "libpspp/temp-file.h" +#include "libpspp/hmapx.h" +#include "libpspp/hash-functions.h" #include @@ -36,29 +38,59 @@ - It honors the $TMPDIR environment variable. - - The file will not be automatically deleted upon close. You have to call - close_temp_file() if you want it to be deleted before the process exits. */ + + +static struct temp_dir *temp_dir; +struct hmapx map; + +static void +setup (void) +{ + hmapx_init (&map); + temp_dir = create_temp_dir ("pspp", NULL, true); +} + +static void +cleanup (void) +{ + struct hmapx_node *node; + const char *fn; + + cleanup_temp_dir (temp_dir); + + HMAPX_FOR_EACH (fn, node, &map) + { + free (fn); + } + + hmapx_destroy (&map); +} + FILE * create_temp_file (void) { static int idx = 0; - static struct temp_dir *temp_dir; char *file_name; FILE *stream; if (temp_dir == NULL) { - temp_dir = create_temp_dir ("pspp", NULL, true); + setup (); if (temp_dir == NULL) return NULL; + atexit (cleanup); } file_name = xasprintf ("%s/%d", temp_dir->dir_name, idx++); + register_temp_file (temp_dir, file_name); stream = fopen_temp (file_name, "wb+"); - if (stream != NULL) + if (stream == NULL) + unregister_temp_file (temp_dir, file_name); + else setvbuf (stream, NULL, _IOFBF, 65536); - free (file_name); + + hmapx_insert (&map, file_name, hash_pointer (stream, 0)); return stream; } @@ -68,5 +100,12 @@ void close_temp_file (FILE *file) { if (file != NULL) - fclose_temp (file); + { + struct hmapx_node *node = hmapx_first_with_hash (&map, hash_pointer (file, 0)); + char *fn = node->data; + fclose_temp (file); + cleanup_temp_file (temp_dir, fn); + hmapx_delete (&map, node); + free (fn); + } } diff --git a/tests/automake.mk b/tests/automake.mk index 840f56b047..dceb82f74b 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -63,6 +63,7 @@ tests_libpspp_heap_test_SOURCES = \ src/libpspp/temp-file.c \ tests/libpspp/heap-test.c tests_libpspp_heap_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 +tests_libpspp_heap_test_LDADD = src/libpspp/libpspp.la gl/libgl.la tests_libpspp_hmap_test_SOURCES = \ src/libpspp/hmap.c \ @@ -101,6 +102,7 @@ tests_libpspp_range_set_test_SOURCES = \ src/libpspp/temp-file.c \ tests/libpspp/range-set-test.c tests_libpspp_range_set_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 +tests_libpspp_range_set_test_LDADD = src/libpspp/libpspp.la gl/libgl.la tests_libpspp_str_test_SOURCES = \ tests/libpspp/str-test.c @@ -113,6 +115,7 @@ tests_libpspp_string_map_test_SOURCES = \ src/libpspp/string-set.c \ tests/libpspp/string-map-test.c tests_libpspp_string_map_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 +tests_libpspp_string_map_test_LDADD = src/libpspp/libpspp.la gl/libgl.la tests_libpspp_stringi_map_test_SOURCES = \ src/libpspp/hash-functions.c \ @@ -125,6 +128,7 @@ tests_libpspp_stringi_map_test_SOURCES = \ src/libpspp/temp-file.c \ tests/libpspp/stringi-map-test.c tests_libpspp_stringi_map_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 +tests_libpspp_stringi_map_test_LDADD = src/libpspp/libpspp.la gl/libgl.la tests_libpspp_string_set_test_SOURCES = \ src/libpspp/hash-functions.c \ @@ -142,6 +146,7 @@ tests_libpspp_stringi_set_test_SOURCES = \ src/libpspp/temp-file.c \ tests/libpspp/stringi-set-test.c tests_libpspp_stringi_set_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 +tests_libpspp_stringi_set_test_LDADD = src/libpspp/libpspp.la gl/libgl.la tests_libpspp_tower_test_SOURCES = \ src/libpspp/abt.c \ @@ -150,6 +155,7 @@ tests_libpspp_tower_test_SOURCES = \ src/libpspp/tower.c \ tests/libpspp/tower-test.c tests_libpspp_tower_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 +tests_libpspp_tower_test_LDADD = src/libpspp/libpspp.la gl/libgl.la tests_libpspp_u8_istream_test_SOURCES = tests/libpspp/u8-istream-test.c tests_libpspp_u8_istream_test_LDADD = src/libpspp/libpspp.la gl/libgl.la @@ -160,6 +166,7 @@ tests_libpspp_sparse_array_test_SOURCES = \ tests/libpspp/sparse-array-test.c \ src/libpspp/temp-file.c tests_libpspp_sparse_array_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 +tests_libpspp_sparse_array_test_LDADD = src/libpspp/libpspp.la gl/libgl.la tests_libpspp_sparse_xarray_test_SOURCES = \ src/libpspp/argv-parser.c \ @@ -175,6 +182,7 @@ tests_libpspp_sparse_xarray_test_SOURCES = \ src/libpspp/temp-file.c \ tests/libpspp/sparse-xarray-test.c tests_libpspp_sparse_xarray_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10 +tests_libpspp_sparse_xarray_test_LDADD = src/libpspp/libpspp.la gl/libgl.la tests_data_inexactify_SOURCES = tests/data/inexactify.c @@ -201,6 +209,9 @@ tests_language_lexer_scan_test_SOURCES = \ src/libpspp/temp-file.c \ tests/language/lexer/scan-test.c tests_language_lexer_scan_test_CFLAGS = $(AM_CFLAGS) +tests_language_lexer_scan_test_LDADD = \ + src/libpspp/libpspp.la \ + gl/libgl.la check_PROGRAMS += tests/language/lexer/segment-test tests_language_lexer_segment_test_SOURCES = \ @@ -213,6 +224,9 @@ tests_language_lexer_segment_test_SOURCES = \ src/libpspp/temp-file.c \ tests/language/lexer/segment-test.c tests_language_lexer_segment_test_CFLAGS = $(AM_CFLAGS) +tests_language_lexer_segment_test_LDADD = \ + src/libpspp/libpspp.la \ + gl/libgl.la check_PROGRAMS += tests/libpspp/zip-test tests_libpspp_zip_test_SOURCES = \ @@ -224,6 +238,9 @@ tests_libpspp_zip_test_SOURCES = \ src/libpspp/zip-writer.c \ tests/libpspp/zip-test.c tests_libpspp_zip_test_CFLAGS = $(AM_CFLAGS) +tests_libpspp_zip_test_LDADD = \ + src/libpspp/libpspp.la \ + gl/libgl.la check_PROGRAMS += tests/output/render-test -- 2.30.2