X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fext-array.c;h=c03d0c23c01b42cb136467c47f031e6218f85ac9;hb=32538f9f35aee7145a49971f9dae1394a1a201b5;hp=b1eded3a3f4d41e658dd2c5aad57d4991e251bc7;hpb=e99991940478d76062c4ab8e44a5747354e33259;p=pspp diff --git a/src/libpspp/ext-array.c b/src/libpspp/ext-array.c index b1eded3a3f..c03d0c23c0 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 @@ -20,6 +20,7 @@ #include #include "libpspp/ext-array.h" +#include "libpspp/message.h" #include #include @@ -29,12 +30,18 @@ #include "libpspp/cast.h" #include "libpspp/temp-file.h" -#include "gl/error.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. */ @@ -44,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. */ @@ -53,8 +63,9 @@ ext_array_create (void) struct ext_array *ea = xmalloc (sizeof *ea); 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; } @@ -68,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; @@ -79,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) { @@ -93,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; @@ -112,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; } @@ -133,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; } @@ -145,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,