#include <config.h>
#include "libpspp/temp-file.h"
+#include "libpspp/hmapx.h"
+#include "libpspp/hash-functions.h"
#include <stdlib.h>
- 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;
}
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);
+ }
}