pspp.git - GNU PSPP

index : pspp.git
GNU PSPP
summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBen Pfaff <blp@cs.stanford.edu>2010年07月29日 22:08:33 -0700
committerBen Pfaff <blp@cs.stanford.edu>2010年07月29日 22:08:33 -0700
commite99991940478d76062c4ab8e44a5747354e33259 (patch)
tree0ebcf81bfbaf891f3c644cd4324c8f7a875bc8a8 /src
parent1d57a8b4c556e227cd562dcfa56c8cbce79f73a8 (diff)
downloadpspp-e99991940478d76062c4ab8e44a5747354e33259.tar.gz
temp-file: New functions for creating temporary files honoring $TMPDIR.
The tmpfile() function is useful, but it doesn't necessarily honor the $TMPDIR environment variable. Some of our users find that a problem, so this commit replaces tmpfile() usage by a new pair of functions create_temp_file() and close_temp_file() that do honor $TMPDIR. Bug #30530.
Diffstat (limited to 'src')
-rw-r--r--src/language/stats/flip.c 10
-rw-r--r--src/libpspp/automake.mk 2
-rw-r--r--src/libpspp/ext-array.c 13
-rw-r--r--src/libpspp/pool.c 85
-rw-r--r--src/libpspp/pool.h 9
-rw-r--r--src/libpspp/temp-file.c 70
-rw-r--r--src/libpspp/temp-file.h 27
-rw-r--r--src/output/odt.c 15
8 files changed, 189 insertions, 42 deletions
diff --git a/src/language/stats/flip.c b/src/language/stats/flip.c
index 8f73c1deb..de7f52c04 100644
--- a/src/language/stats/flip.c
+++ b/src/language/stats/flip.c
@@ -144,7 +144,7 @@ cmd_flip (struct lexer *lexer, struct dataset *ds)
}
}
- 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."));
@@ -328,7 +328,7 @@ flip_file (struct flip_pgm *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."));
@@ -379,11 +379,7 @@ flip_file (struct flip_pgm *flip)
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);
diff --git a/src/libpspp/automake.mk b/src/libpspp/automake.mk
index 5cf669553..de7912bb0 100644
--- a/src/libpspp/automake.mk
+++ b/src/libpspp/automake.mk
@@ -84,6 +84,8 @@ src_libpspp_libpspp_la_SOURCES = \
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 \
diff --git a/src/libpspp/ext-array.c b/src/libpspp/ext-array.c
index df3b589fe..b1eded3a3 100644
--- a/src/libpspp/ext-array.c
+++ b/src/libpspp/ext-array.c
@@ -19,17 +19,18 @@
#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)
@@ -50,7 +51,7 @@ struct ext_array *
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;
diff --git a/src/libpspp/pool.c b/src/libpspp/pool.c
index dbdd71b6c..7a8a591da 100644
--- a/src/libpspp/pool.c
+++ b/src/libpspp/pool.c
@@ -1,5 +1,5 @@
/* 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
@@ -15,14 +15,18 @@
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
@@ -45,6 +49,7 @@ enum
{
POOL_GIZMO_MALLOC,
POOL_GIZMO_FILE,
+ POOL_GIZMO_TEMP_FILE,
POOL_GIZMO_SUBPOOL,
POOL_GIZMO_REGISTERED,
};
@@ -64,7 +69,7 @@ struct pool_gizmo
/* 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. */
@@ -755,41 +760,78 @@ pool_fclose (struct pool *pool, FILE *file)
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;
@@ -947,6 +989,9 @@ free_gizmo (struct pool_gizmo *gizmo)
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);
diff --git a/src/libpspp/pool.h b/src/libpspp/pool.h
index fc24b2f9e..da95f4ec7 100644
--- a/src/libpspp/pool.h
+++ b/src/libpspp/pool.h
@@ -1,5 +1,5 @@
/* 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
@@ -85,10 +85,15 @@ void pool_add_subpool (struct pool *, struct pool *subpool);
/* 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 *);
diff --git a/src/libpspp/temp-file.c b/src/libpspp/temp-file.c
new file mode 100644
index 000000000..c1ffbea66
--- /dev/null
+++ b/src/libpspp/temp-file.c
@@ -0,0 +1,70 @@
+/* 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);
+}
diff --git a/src/libpspp/temp-file.h b/src/libpspp/temp-file.h
new file mode 100644
index 000000000..499c1e348
--- /dev/null
+++ b/src/libpspp/temp-file.h
@@ -0,0 +1,27 @@
+/* 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 */
diff --git a/src/output/odt.c b/src/output/odt.c
index 49a55b4cc..906323964 100644
--- a/src/output/odt.c
+++ b/src/output/odt.c
@@ -32,6 +32,7 @@
#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"
@@ -87,7 +88,7 @@ create_mimetype (struct zip_writer *zip)
{
FILE *fp;
- fp = tmpfile ();
+ fp = create_temp_file ();
if (fp == NULL)
{
error (0, errno, _("error creating temporary file"));
@@ -96,7 +97,7 @@ create_mimetype (struct zip_writer *zip)
fprintf (fp, "application/vnd.oasis.opendocument.text");
zip_writer_add (zip, fp, "mimetype");
- fclose (fp);
+ close_temp_file (fp);
return true;
}
@@ -107,7 +108,7 @@ static void
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);
@@ -218,7 +219,7 @@ write_style_data (struct odt_driver *odt)
xmlTextWriterEndDocument (w);
xmlFreeTextWriter (w);
zip_writer_add (odt->zip, file, "styles.xml");
- fclose (file);
+ close_temp_file (file);
}
static void
@@ -282,7 +283,7 @@ write_meta_data (struct odt_driver *odt)
xmlTextWriterEndDocument (w);
xmlFreeTextWriter (w);
zip_writer_add (odt->zip, file, "meta.xml");
- fclose (file);
+ close_temp_file (file);
}
static struct output_driver *
@@ -355,7 +356,7 @@ odt_create (const char *file_name, enum settings_output_devices device_type,
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;
}
@@ -374,7 +375,7 @@ odt_destroy (struct output_driver *driver)
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);
}
generated by cgit v1.2.3 (git 2.25.1) at 2025年10月06日 04:13:23 +0000

AltStyle によって変換されたページ (->オリジナル) /