X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fext-array.c;h=e5287fcc75d1637970cd0361ddddca4155d9a752;hb=7caed4c8228cf00ed5061b474f32a47b5ff7c40f;hp=b1eded3a3f4d41e658dd2c5aad57d4991e251bc7;hpb=e99991940478d76062c4ab8e44a5747354e33259;p=pspp diff --git a/src/libpspp/ext-array.c b/src/libpspp/ext-array.c index b1eded3a3f..e5287fcc75 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 @@ -30,11 +30,18 @@ #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. */ @@ -55,6 +65,7 @@ ext_array_create (void) if (ea->file == NULL) error (0, 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) { @@ -120,6 +130,7 @@ do_read (const struct ext_array *ea_, void *buffer, size_t bytes) return false; } ea->position += bytes; + ea->op = OP_READ; return true; } @@ -137,6 +148,7 @@ do_write (struct ext_array *ea, const void *buffer, size_t bytes) 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,