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).
This commit is contained in:
Noah Misch 2017-03-12 19:35:31 -04:00
parent c4613c3f49
commit 0276da5eb3
1 changed files with 7 additions and 12 deletions

View File

@ -141,10 +141,10 @@ pg_file_write(PG_FUNCTION_ARGS)
(ERRCODE_DUPLICATE_FILE, (ERRCODE_DUPLICATE_FILE,
errmsg("file \"%s\" exists", filename))); errmsg("file \"%s\" exists", filename)));
f = fopen(filename, "wb"); f = AllocateFile(filename, "wb");
} }
else else
f = fopen(filename, "ab"); f = AllocateFile(filename, "ab");
if (!f) if (!f)
ereport(ERROR, ereport(ERROR,
@ -152,16 +152,11 @@ pg_file_write(PG_FUNCTION_ARGS)
errmsg("could not open file \"%s\" for writing: %m", errmsg("could not open file \"%s\" for writing: %m",
filename))); filename)));
if (VARSIZE(data) != 0)
{
count = fwrite(VARDATA(data), 1, VARSIZE(data) - VARHDRSZ, f); count = fwrite(VARDATA(data), 1, VARSIZE(data) - VARHDRSZ, f);
if (count != VARSIZE(data) - VARHDRSZ || FreeFile(f))
if (count != VARSIZE(data) - VARHDRSZ)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not write file \"%s\": %m", filename))); errmsg("could not write file \"%s\": %m", filename)));
}
fclose(f);
PG_RETURN_INT64(count); PG_RETURN_INT64(count);
} }