X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Ftemp-file.c;h=cc90a37559b2cb532e8cc60f5589da531b8bd211;hb=5cc8d996ceb67400912b46199ae658cdfbfea180;hp=ffd5da7cef162dfdaef2ab20e66513b33b67b5ba;hpb=fe8dc2171009e90d2335f159d05f7e6660e24780;p=pspp diff --git a/src/libpspp/temp-file.c b/src/libpspp/temp-file.c index ffd5da7cef..cc90a37559 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,80 @@ - 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 void cleanup (void); + +static struct temp_dir *temp_dir; +static struct hmapx map; + +static void +setup (void) +{ + hmapx_init (&map); + temp_dir = create_temp_dir ("pspp", NULL, true); +} + +static void +initialise (void) +{ + if (temp_dir == NULL) + { + setup (); + if (temp_dir == NULL) + return ; + atexit (cleanup); + } +} + + +const char * +temp_dir_name (void) +{ + initialise (); + + if (temp_dir) + return temp_dir->dir_name; + + return NULL; +} + +static void +cleanup (void) +{ + struct hmapx_node *node; + 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; + initialise (); if (temp_dir == NULL) - { - temp_dir = create_temp_dir ("pspp", NULL, true); - if (temp_dir == NULL) - return NULL; - } + return NULL; file_name = xasprintf ("%s/%d", temp_dir->dir_name, idx++); - stream = fopen_temp (file_name, "wb+"); - if (stream != NULL) + register_temp_file (temp_dir, file_name); + stream = fopen_temp (file_name, "wb+", true); + 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 +121,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); + } }