X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Ftemp-file.c;h=c1ffbea664dc6e7cce73fef03584f45d65bd024f;hb=refs%2Fbuilds%2F126%2Fpspp;hp=554a6d7d5f74276774057905fe2e71ef318df919;hpb=70514b3f2f32d57e58b04c01c83bc5f372559824;p=pspp diff --git a/src/libpspp/temp-file.c b/src/libpspp/temp-file.c index 554a6d7d5f..c1ffbea664 100644 --- a/src/libpspp/temp-file.c +++ b/src/libpspp/temp-file.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. + 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 @@ -14,154 +14,57 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -/* A interface to allow a temporary file to be treated as an - array of data. */ +/* Functions for temporary files that honor $TMPDIR. */ #include -#include +#include "libpspp/temp-file.h" -#include -#include #include -#include -#include +#include "gl/clean-temp.h" +#include "gl/xvasprintf.h" -#include "error.h" -#include "xalloc.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. -#include "gettext.h" -#define _(msgid) gettext (msgid) + Returns NULL if creating the temporary file fails. -struct temp_file - { - FILE *file; /* Underlying file. */ + This is similar to tmpfile(), except: - /* Current byte offset in file. We track this manually, - instead of using ftello, because in glibc ftello flushes - the stream buffer, making the common case of sequential - access to cases unreasonably slow. */ - off_t position; - }; + - It honors the $TMPDIR environment variable. -/* Creates and returns a new temporary file. The temporary file - will be automatically deleted when the process exits. */ -struct temp_file * -temp_file_create (void) + - 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) { - struct temp_file *tf = xmalloc (sizeof *tf); - tf->file = tmpfile (); - if (tf->file == NULL) - error (0, errno, _("failed to create temporary file")); - tf->position = 0; - return tf; -} - -/* Closes and destroys temporary file TF. Returns true if I/O on - TF always succeeded, false if an I/O error occurred at some - point. */ -bool -temp_file_destroy (struct temp_file *tf) -{ - bool ok = true; - if (tf != NULL) - { - ok = !temp_file_error (tf); - if (tf->file != NULL) - fclose (tf->file); - free (tf); - } - return ok; -} - -/* Seeks TF's underlying file to the start of `union value' - VALUE_IDX within case CASE_IDX. - Returns true if the seek is successful and TF is not - otherwise tainted, false otherwise. */ -static bool -do_seek (const struct temp_file *tf_, off_t offset) -{ - struct temp_file *tf = CONST_CAST (struct temp_file *, tf_); - - if (!temp_file_error (tf)) - { - if (tf->position == offset) - return true; - else if (fseeko (tf->file, offset, SEEK_SET) == 0) - { - tf->position = offset; - return true; - } - else - error (0, errno, _("seeking in temporary file")); - } - - return false; -} - -/* Reads BYTES bytes from TF's underlying file into BUFFER. - TF must not be tainted upon entry into this function. - Returns true if successful, false upon an I/O error (in which - case TF is marked tainted). */ -static bool -do_read (const struct temp_file *tf_, void *buffer, size_t bytes) -{ - struct temp_file *tf = CONST_CAST (struct temp_file *, tf_); - - assert (!temp_file_error (tf)); - if (bytes > 0 && fread (buffer, bytes, 1, tf->file) != 1) - { - if (ferror (tf->file)) - error (0, errno, _("reading temporary file")); - else if (feof (tf->file)) - error (0, 0, _("unexpected end of file reading temporary file")); - else - NOT_REACHED (); - return false; - } - tf->position += bytes; - return true; -} + static int idx = 0; + static struct temp_dir *temp_dir; + char *file_name; + FILE *stream; -/* Writes BYTES bytes from BUFFER into TF's underlying file. - TF must not be tainted upon entry into this function. - Returns true if successful, false upon an I/O error (in which - case TF is marked tainted). */ -static bool -do_write (struct temp_file *tf, const void *buffer, size_t bytes) -{ - assert (!temp_file_error (tf)); - if (bytes > 0 && fwrite (buffer, bytes, 1, tf->file) != 1) + if (temp_dir == NULL) { - error (0, errno, _("writing to temporary file")); - return false; + temp_dir = create_temp_dir ("pspp", NULL, true); + if (temp_dir == NULL) + return NULL; } - tf->position += bytes; - return true; -} -/* Reads N bytes from TF at byte offset OFFSET into DATA. - Returns true if successful, false on failure. */ -bool -temp_file_read (const struct temp_file *tf, off_t offset, size_t n, void *data) -{ - return do_seek (tf, offset) && do_read (tf, data, n); -} + file_name = xasprintf ("%s/%d", temp_dir->dir_name, idx++); + stream = fopen_temp (file_name, "wb+"); + free (file_name); -/* Writes the N bytes in DATA to TF at byte offset OFFSET. - Returns true if successful, false on failure. */ -bool -temp_file_write (struct temp_file *tf, off_t offset, size_t n, - const void *data) -{ - return do_seek (tf, offset) && do_write (tf, data, n); + return stream; } -/* Returns true if an error has occurred in I/O on TF, - false if no error has been detected. */ -bool -temp_file_error (const struct temp_file *tf) +/* Closes and removes a temporary file created by create_temp_file(). */ +void +close_temp_file (FILE *file) { - return tf->file == NULL || ferror (tf->file) || feof (tf->file); + if (file != NULL) + fclose_temp (file); }