aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/file/buffile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/file/buffile.c')
-rw-r--r--src/backend/storage/file/buffile.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index 4a5bd0e224d..c5464b6aa62 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -573,14 +573,19 @@ BufFileDumpBuffer(BufFile *file)
}
/*
- * BufFileRead
+ * BufFileRead variants
*
* Like fread() except we assume 1-byte element size and report I/O errors via
* ereport().
+ *
+ * If 'exact' is true, then an error is also raised if the number of bytes
+ * read is not exactly 'size' (no short reads). If 'exact' and 'eofOK' are
+ * true, then reading zero bytes is ok.
*/
-size_t
-BufFileRead(BufFile *file, void *ptr, size_t size)
+static size_t
+BufFileReadCommon(BufFile *file, void *ptr, size_t size, bool exact, bool eofOK)
{
+ size_t start_size = size;
size_t nread = 0;
size_t nthistime;
@@ -612,10 +617,49 @@ BufFileRead(BufFile *file, void *ptr, size_t size)
nread += nthistime;
}
+ if (exact &&
+ (nread != start_size && !(nread == 0 && eofOK)))
+ ereport(ERROR,
+ errcode_for_file_access(),
+ file->name ?
+ errmsg("could not read from file set \"%s\": read only %zu of %zu bytes",
+ file->name, nread, start_size) :
+ errmsg("could not read from temporary file: read only %zu of %zu bytes",
+ nread, start_size));
+
return nread;
}
/*
+ * Legacy interface where the caller needs to check for end of file or short
+ * reads.
+ */
+size_t
+BufFileRead(BufFile *file, void *ptr, size_t size)
+{
+ return BufFileReadCommon(file, ptr, size, false, false);
+}
+
+/*
+ * Require read of exactly the specified size.
+ */
+void
+BufFileReadExact(BufFile *file, void *ptr, size_t size)
+{
+ BufFileReadCommon(file, ptr, size, true, false);
+}
+
+/*
+ * Require read of exactly the specified size, but optionally allow end of
+ * file (in which case 0 is returned).
+ */
+size_t
+BufFileReadMaybeEOF(BufFile *file, void *ptr, size_t size, bool eofOK)
+{
+ return BufFileReadCommon(file, ptr, size, true, eofOK);
+}
+
+/*
* BufFileWrite
*
* Like fwrite() except we assume 1-byte element size and report errors via