X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fext-array.c;h=9129d365d6e10f66e1206432541cc2c492093dbc;hb=8e98d2ec1b1620280d66820e323d82b00975374e;hp=df3b589fe0c893dad1828c52e86b2542ce78f5b4;hpb=1d57a8b4c556e227cd562dcfa56c8cbce79f73a8;p=pspp diff --git a/src/libpspp/ext-array.c b/src/libpspp/ext-array.c index df3b589fe0..9129d365d6 100644 --- a/src/libpspp/ext-array.c +++ b/src/libpspp/ext-array.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2007, 2009, 2010, 2011, 2012 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 @@ -19,21 +19,29 @@ #include -#include +#include "libpspp/ext-array.h" +#include "libpspp/message.h" #include #include #include -#include -#include +#include "libpspp/assertion.h" +#include "libpspp/cast.h" +#include "libpspp/temp-file.h" -#include "error.h" -#include "xalloc.h" +#include "gl/unlocked-io.h" +#include "gl/xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) +enum op + { + OP_WRITE, /* writing */ + OP_READ /* reading */ + }; + struct ext_array { FILE *file; /* Underlying file. */ @@ -43,6 +51,9 @@ struct ext_array the stream buffer, making the common case of sequential access to cases unreasonably slow. */ off_t position; + + /* The most recent operation performed */ + enum op op; }; /* Creates and returns a new external array. */ @@ -50,10 +61,11 @@ 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")); + msg_error (errno, _("failed to create temporary file")); ea->position = 0; + ea->op = OP_WRITE; return ea; } @@ -67,7 +79,7 @@ ext_array_destroy (struct ext_array *ea) { ok = !ext_array_error (ea); if (ea->file != NULL) - fclose (ea->file); + close_temp_file (ea->file); free (ea); } return ok; @@ -78,13 +90,12 @@ ext_array_destroy (struct ext_array *ea) Returns true if the seek is successful and EA is not otherwise tainted, false otherwise. */ static bool -do_seek (const struct ext_array *ea_, off_t offset) +do_seek (const struct ext_array *ea_, off_t offset, enum op op) { struct ext_array *ea = CONST_CAST (struct ext_array *, ea_); - if (!ext_array_error (ea)) { - if (ea->position == offset) + if (ea->position == offset && ea->op == op) return true; else if (fseeko (ea->file, offset, SEEK_SET) == 0) { @@ -92,7 +103,7 @@ do_seek (const struct ext_array *ea_, off_t offset) return true; } else - error (0, errno, _("seeking in temporary file")); + msg_error (errno, _("seeking in temporary file")); } return false; @@ -111,14 +122,15 @@ do_read (const struct ext_array *ea_, void *buffer, size_t bytes) if (bytes > 0 && fread (buffer, bytes, 1, ea->file) != 1) { if (ferror (ea->file)) - error (0, errno, _("reading temporary file")); + msg_error (errno, _("reading temporary file")); else if (feof (ea->file)) - error (0, 0, _("unexpected end of file reading temporary file")); + msg_error ( 0, _("unexpected end of file reading temporary file")); else NOT_REACHED (); return false; } ea->position += bytes; + ea->op = OP_READ; return true; } @@ -132,10 +144,11 @@ do_write (struct ext_array *ea, const void *buffer, size_t bytes) assert (!ext_array_error (ea)); if (bytes > 0 && fwrite (buffer, bytes, 1, ea->file) != 1) { - error (0, errno, _("writing to temporary file")); + msg_error (errno, _("writing to temporary file")); return false; } ea->position += bytes; + ea->op = OP_WRITE; return true; } @@ -144,16 +157,17 @@ do_write (struct ext_array *ea, const void *buffer, size_t bytes) bool ext_array_read (const struct ext_array *ea, off_t offset, size_t n, void *data) { - return do_seek (ea, offset) && do_read (ea, data, n); + return do_seek (ea, offset, OP_READ) && do_read (ea, data, n); } + /* Writes the N bytes in DATA to EA at byte offset OFFSET. Returns true if successful, false on failure. */ bool ext_array_write (struct ext_array *ea, off_t offset, size_t n, const void *data) { - return do_seek (ea, offset) && do_write (ea, data, n); + return do_seek (ea, offset, OP_WRITE) && do_write (ea, data, n); } /* Returns true if an error has occurred in I/O on EA,