byteswap \
c-ctype \
c-strtod \
+ clean-temp \
close \
configmake \
count-one-bits \
strtoul \
sys_stat \
tempname \
- tmpfile \
trunc \
unilbrk/ulc-width-linebreaks \
unistd \
}
}
- flip->file = pool_tmpfile (flip->pool);
+ flip->file = pool_create_temp_file (flip->pool);
if (flip->file == NULL)
{
msg (SE, _("Could not create temporary file for FLIP."));
return false;
}
- output_file = pool_tmpfile (flip->pool);
+ output_file = pool_create_temp_file (flip->pool);
if (output_file == NULL)
{
msg (SE, _("Error creating FLIP source file."));
case_idx += read_cases;
}
- if (pool_fclose (flip->pool, input_file) == EOF)
- {
- msg (SE, _("Error closing FLIP source file: %s."), strerror (errno));
- return false;
- }
+ pool_fclose_temp_file (flip->pool, input_file);
pool_unregister (flip->pool, input_buf);
free (input_buf);
src/libpspp/str.h \
src/libpspp/taint.c \
src/libpspp/taint.h \
+ src/libpspp/temp-file.c \
+ src/libpspp/temp-file.h \
src/libpspp/tower.c \
src/libpspp/tower.h \
src/libpspp/version.h \
#include <config.h>
-#include <libpspp/ext-array.h>
+#include "libpspp/ext-array.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
-#include <libpspp/assertion.h>
-#include <libpspp/cast.h>
+#include "libpspp/assertion.h"
+#include "libpspp/cast.h"
+#include "libpspp/temp-file.h"
-#include "error.h"
-#include "xalloc.h"
+#include "gl/error.h"
+#include "gl/xalloc.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
ext_array_create (void)
{
struct ext_array *ea = xmalloc (sizeof *ea);
- ea->file = tmpfile ();
+ ea->file = create_temp_file ();
if (ea->file == NULL)
error (0, errno, _("failed to create temporary file"));
ea->position = 0;
/* PSPP - a program for statistical analysis.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
-#include "pool.h"
+
+#include "libpspp/pool.h"
+
#include <stdint.h>
#include <stdlib.h>
-#include <libpspp/assertion.h>
-#include "message.h"
-#include "str.h"
-#include "xalloc.h"
+#include "libpspp/assertion.h"
+#include "libpspp/message.h"
+#include "libpspp/temp-file.h"
+#include "libpspp/str.h"
+
+#include "gl/xalloc.h"
/* Fast, low-overhead memory block suballocator. */
struct pool
{
POOL_GIZMO_MALLOC,
POOL_GIZMO_FILE,
+ POOL_GIZMO_TEMP_FILE,
POOL_GIZMO_SUBPOOL,
POOL_GIZMO_REGISTERED,
};
/* Type-dependent info. */
union
{
- FILE *file; /* POOL_GIZMO_FILE. */
+ FILE *file; /* POOL_GIZMO_FILE, POOL_GIZMO_TEMP_FILE. */
struct pool *subpool; /* POOL_GIZMO_SUBPOOL. */
/* POOL_GIZMO_REGISTERED. */
return fclose (file);
}
-/* Creates a temporary file with tmpfile() and returns a handle to it
- if successful or a null pointer if not.
+/* Attaches FILE to POOL.
The file will be closed automatically when POOL is destroyed, or it
may be closed explicitly in advance using pool_fclose(), or
detached from the pool with pool_detach_file(). */
+void
+pool_attach_file (struct pool *pool, FILE *file)
+{
+ struct pool_gizmo *g = pool_alloc (pool, sizeof *g);
+ g->type = POOL_GIZMO_FILE;
+ g->p.file = file;
+ add_gizmo (pool, g);
+}
+
+/* Detaches FILE from POOL. */
+void
+pool_detach_file (struct pool *pool, FILE *file)
+{
+ struct pool_gizmo *g;
+
+ for (g = pool->gizmos; g; g = g->next)
+ if (g->type == POOL_GIZMO_FILE && g->p.file == file)
+ {
+ delete_gizmo (pool, g);
+ return;
+ }
+}
+
+/* Creates a temporary file with create_temp_file() and returns a handle to it
+ if successful or a null pointer if not.
+ The file will be closed automatically when POOL is destroyed, or it
+ may be closed explicitly in advance using pool_fclose_temp_file(), or
+ detached from the pool with pool_detach_temp_file(). */
FILE *
-pool_tmpfile (struct pool *pool)
+pool_create_temp_file (struct pool *pool)
{
- FILE *file = tmpfile ();
+ FILE *file = create_temp_file ();
if (file != NULL)
- pool_attach_file (pool, file);
+ pool_attach_temp_file (pool, file);
return file;
}
-/* Attaches FILE to POOL.
+/* Closes file FILE managed by POOL.
+ FILE must have been opened with create_temp_file(). */
+void
+pool_fclose_temp_file (struct pool *pool, FILE *file)
+{
+ assert (pool && file);
+ pool_detach_temp_file (pool, file);
+ close_temp_file (file);
+}
+
+/* Attaches FILE, which must have been opened with create_temp_file(), to POOL.
The file will be closed automatically when POOL is destroyed, or it
- may be closed explicitly in advance using pool_fclose(), or
- detached from the pool with pool_detach_file(). */
+ may be closed explicitly in advance using pool_fclose_temp_file(), or
+ detached from the pool with pool_detach_temp_file(). */
void
-pool_attach_file (struct pool *pool, FILE *file)
+pool_attach_temp_file (struct pool *pool, FILE *file)
{
struct pool_gizmo *g = pool_alloc (pool, sizeof *g);
- g->type = POOL_GIZMO_FILE;
+ g->type = POOL_GIZMO_TEMP_FILE;
g->p.file = file;
add_gizmo (pool, g);
}
-/* Detaches FILE from POOL. */
+/* Detaches FILE that was opened with create_temp_file() from POOL. */
void
-pool_detach_file (struct pool *pool, FILE *file)
+pool_detach_temp_file (struct pool *pool, FILE *file)
{
struct pool_gizmo *g;
for (g = pool->gizmos; g; g = g->next)
- if (g->type == POOL_GIZMO_FILE && g->p.file == file)
+ if (g->type == POOL_GIZMO_TEMP_FILE && g->p.file == file)
{
delete_gizmo (pool, g);
return;
case POOL_GIZMO_FILE:
fclose (gizmo->p.file); /* Ignore errors. */
break;
+ case POOL_GIZMO_TEMP_FILE:
+ close_temp_file (gizmo->p.file); /* Ignore errors. */
+ break;
case POOL_GIZMO_SUBPOOL:
gizmo->p.subpool->parent = NULL;
pool_destroy (gizmo->p.subpool);
/* PSPP - a program for statistical analysis.
- Copyright (C) 2000, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2006, 2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/* Files. */
FILE *pool_fopen (struct pool *, const char *, const char *);
int pool_fclose (struct pool *, FILE *) WARN_UNUSED_RESULT;
-FILE *pool_tmpfile (struct pool *);
void pool_attach_file (struct pool *, FILE *);
void pool_detach_file (struct pool *, FILE *);
+/* Temporary files. */
+FILE *pool_create_temp_file (struct pool *);
+void pool_fclose_temp_file (struct pool *, FILE *);
+void pool_attach_temp_file (struct pool *, FILE *);
+void pool_detach_temp_file (struct pool *, FILE *);
+
/* Custom allocations. */
void pool_register (struct pool *, void (*free) (void *), void *p);
bool pool_unregister (struct pool *, void *);
--- /dev/null
+/* PSPP - a program for statistical analysis.
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Functions for temporary files that honor $TMPDIR. */
+
+#include <config.h>
+
+#include "libpspp/temp-file.h"
+
+#include <stdlib.h>
+
+#include "gl/clean-temp.h"
+#include "gl/xvasprintf.h"
+
+/* Creates and returns a new temporary file that will be removed automatically
+ when the process exits. The file is opened in mode "wb+". To close the
+ file before the process exits, use close_temp_file() to ensure that it gets
+ deleted early.
+
+ Returns NULL if creating the temporary file fails.
+
+ This is similar to tmpfile(), except:
+
+ - 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.
+*/
+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);
+ if (temp_dir == NULL)
+ return NULL;
+ }
+
+ file_name = xasprintf ("%s/%d", temp_dir->dir_name, idx++);
+ stream = fopen_temp (file_name, "wb+");
+ free (file_name);
+
+ return stream;
+}
+
+/* Closes and removes a temporary file created by create_temp_file(). */
+void
+close_temp_file (FILE *file)
+{
+ if (file != NULL)
+ fclose_temp (file);
+}
--- /dev/null
+/* PSPP - a program for statistical analysis.
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Functions for temporary files that honor $TMPDIR. */
+
+#ifndef LIBPSPP_TEMP_FILE_H
+#define LIBPSPP_TEMP_FILE_H 1
+
+#include <stdio.h>
+
+FILE *create_temp_file (void);
+void close_temp_file (FILE *);
+
+#endif /* libpspp/ext-array.h */
#include "libpspp/assertion.h"
#include "libpspp/cast.h"
#include "libpspp/str.h"
+#include "libpspp/temp-file.h"
#include "libpspp/version.h"
#include "libpspp/zip-writer.h"
#include "output/driver-provider.h"
{
FILE *fp;
- fp = tmpfile ();
+ fp = create_temp_file ();
if (fp == NULL)
{
error (0, errno, _("error creating temporary file"));
fprintf (fp, "application/vnd.oasis.opendocument.text");
zip_writer_add (zip, fp, "mimetype");
- fclose (fp);
+ close_temp_file (fp);
return true;
}
create_writer (FILE **file, xmlTextWriterPtr *w)
{
/* XXX this can fail */
- *file = tmpfile ();
+ *file = create_temp_file ();
*w = xmlNewTextWriter (xmlOutputBufferCreateFile (*file, NULL));
xmlTextWriterStartDocument (*w, NULL, "UTF-8", NULL);
xmlTextWriterEndDocument (w);
xmlFreeTextWriter (w);
zip_writer_add (odt->zip, file, "styles.xml");
- fclose (file);
+ close_temp_file (file);
}
static void
xmlTextWriterEndDocument (w);
xmlFreeTextWriter (w);
zip_writer_add (odt->zip, file, "meta.xml");
- fclose (file);
+ close_temp_file (file);
}
static struct output_driver *
xmlTextWriterEndDocument (odt->manifest_wtr);
xmlFreeTextWriter (odt->manifest_wtr);
zip_writer_add (odt->zip, odt->manifest_file, "META-INF/manifest.xml");
- fclose (odt->manifest_file);
+ close_temp_file (odt->manifest_file);
return d;
}
xmlTextWriterEndDocument (odt->content_wtr);
xmlFreeTextWriter (odt->content_wtr);
zip_writer_add (odt->zip, odt->content_file, "content.xml");
- fclose (odt->content_file);
+ close_temp_file (odt->content_file);
zip_writer_close (odt->zip);
}
src/libpspp/heap.h \
src/libpspp/pool.c \
src/libpspp/pool.h \
+ src/libpspp/temp-file.c \
tests/libpspp/heap-test.c
tests_libpspp_heap_test_LDADD = gl/libgl.la $(LIBINTL)
tests_libpspp_heap_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10
src/libpspp/pool.h \
src/libpspp/range-set.c \
src/libpspp/range-set.h \
+ src/libpspp/temp-file.c \
tests/libpspp/range-set-test.c
tests_libpspp_range_set_test_LDADD = gl/libgl.la $(LIBINTL)
tests_libpspp_range_set_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10
src/libpspp/stringi-map.c \
src/libpspp/string-set.c \
src/libpspp/stringi-set.c \
+ src/libpspp/temp-file.c \
tests/libpspp/stringi-map-test.c
tests_libpspp_stringi_map_test_LDADD = gl/libgl.la $(LIBINTL)
tests_libpspp_stringi_map_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10
src/libpspp/pool.c \
src/libpspp/str.c \
src/libpspp/stringi-set.c \
+ src/libpspp/temp-file.c \
tests/libpspp/stringi-set-test.c
tests_libpspp_stringi_set_test_LDADD = gl/libgl.la $(LIBINTL)
tests_libpspp_stringi_set_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10
src/libpspp/abt.h \
src/libpspp/pool.c \
src/libpspp/pool.h \
+ src/libpspp/temp-file.c \
src/libpspp/tower.c \
src/libpspp/tower.h \
tests/libpspp/tower-test.c
src/libpspp/sparse-array.h \
src/libpspp/pool.c \
src/libpspp/pool.h \
- tests/libpspp/sparse-array-test.c
+ tests/libpspp/sparse-array-test.c \
+ src/libpspp/temp-file.c
tests_libpspp_sparse_array_test_LDADD = gl/libgl.la $(LIBINTL)
tests_libpspp_sparse_array_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10
src/libpspp/sparse-xarray.c \
src/libpspp/str.c \
src/libpspp/pool.c \
+ src/libpspp/temp-file.c \
tests/libpspp/sparse-xarray-test.c
tests_libpspp_sparse_xarray_test_LDADD = gl/libgl.la $(LIBINTL)
tests_libpspp_sparse_xarray_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10