aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2017-03-12 19:35:31 -0400
committerNoah Misch <noah@leadboat.com>2017-03-12 19:35:49 -0400
commit08c6d42c8c63c62aeaaf71cd6375baef798c5924 (patch)
treea2e9fb4ada99828eda938a58ac28a524831cfe18
parent8469923f3ea893ee0261a234e2e5136663064d52 (diff)
downloadpostgresql-08c6d42c8c63c62aeaaf71cd6375baef798c5924.tar.gz
postgresql-08c6d42c8c63c62aeaaf71cd6375baef798c5924.zip
Fix pg_file_write() error handling.
Detect fclose() failures; given "ln -s /dev/full $PGDATA/devfull", "pg_file_write('devfull', 'x', true)" now fails as it should. Don't leak a stream when fwrite() fails. Remove a born-ineffective test that aimed to skip zero-length writes. Back-patch to 9.2 (all supported versions).
-rw-r--r--contrib/adminpack/adminpack.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/contrib/adminpack/adminpack.c b/contrib/adminpack/adminpack.c
index ea781a0a5a4..67b4a47f4aa 100644
--- a/contrib/adminpack/adminpack.c
+++ b/contrib/adminpack/adminpack.c
@@ -136,10 +136,10 @@ pg_file_write(PG_FUNCTION_ARGS)
(ERRCODE_DUPLICATE_FILE,
errmsg("file \"%s\" exists", filename)));
- f = fopen(filename, "wb");
+ f = AllocateFile(filename, "wb");
}
else
- f = fopen(filename, "ab");
+ f = AllocateFile(filename, "ab");
if (!f)
ereport(ERROR,
@@ -147,16 +147,11 @@ pg_file_write(PG_FUNCTION_ARGS)
errmsg("could not open file \"%s\" for writing: %m",
filename)));
- if (VARSIZE(data) != 0)
- {
- count = fwrite(VARDATA(data), 1, VARSIZE(data) - VARHDRSZ, f);
-
- if (count != VARSIZE(data) - VARHDRSZ)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not write file \"%s\": %m", filename)));
- }
- fclose(f);
+ count = fwrite(VARDATA(data), 1, VARSIZE(data) - VARHDRSZ, f);
+ if (count != VARSIZE(data) - VARHDRSZ || FreeFile(f))
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not write file \"%s\": %m", filename)));
PG_RETURN_INT64(count);
}