1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Properly detect read and write errors in pg_dump/dumpall, and pg_restore

Previously some I/O errors were ignored.
This commit is contained in:
Bruce Momjian
2014-05-05 20:27:16 -04:00
parent 768fb00326
commit 14ea89366f
10 changed files with 237 additions and 207 deletions

View File

@ -35,12 +35,12 @@
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
static void _StartData(ArchiveHandle *AH, TocEntry *te);
static size_t _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
static void _EndData(ArchiveHandle *AH, TocEntry *te);
static int _WriteByte(ArchiveHandle *AH, const int i);
static int _ReadByte(ArchiveHandle *);
static size_t _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
static size_t _ReadBuf(ArchiveHandle *AH, void *buf, size_t len);
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len);
static void _CloseArchive(ArchiveHandle *AH);
static void _ReopenArchive(ArchiveHandle *AH);
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
@ -86,7 +86,7 @@ typedef struct
static void _readBlockHeader(ArchiveHandle *AH, int *type, int *id);
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx);
static size_t _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len);
static void _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len);
static size_t _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen);
/* translator: this is a module name */
@ -315,16 +315,17 @@ _StartData(ArchiveHandle *AH, TocEntry *te)
*
* Mandatory.
*/
static size_t
static void
_WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
{
lclContext *ctx = (lclContext *) AH->formatData;
CompressorState *cs = ctx->cs;
if (dLen == 0)
return 0;
if (dLen > 0)
/* WriteDataToArchive() internally throws write errors */
WriteDataToArchive(AH, cs, data, dLen);
return WriteDataToArchive(AH, cs, data, dLen);
return;
}
/*
@ -579,8 +580,7 @@ _skipData(ArchiveHandle *AH)
buf = (char *) pg_malloc(blkLen);
buflen = blkLen;
}
cnt = fread(buf, 1, blkLen, AH->FH);
if (cnt != blkLen)
if ((cnt = fread(buf, 1, blkLen, AH->FH)) != blkLen)
{
if (feof(AH->FH))
exit_horribly(modulename,
@ -610,14 +610,13 @@ static int
_WriteByte(ArchiveHandle *AH, const int i)
{
lclContext *ctx = (lclContext *) AH->formatData;
int res;
int res;
res = fputc(i, AH->FH);
if (res != EOF)
ctx->filePos += 1;
else
exit_horribly(modulename, "could not write byte: %s\n", strerror(errno));
return res;
if ((res = fputc(i, AH->FH)) == EOF)
WRITE_ERROR_EXIT;
ctx->filePos += 1;
return 1;
}
/*
@ -636,7 +635,7 @@ _ReadByte(ArchiveHandle *AH)
res = getc(AH->FH);
if (res == EOF)
exit_horribly(modulename, "unexpected end of file\n");
READ_ERROR_EXIT(AH->FH);
ctx->filePos += 1;
return res;
}
@ -648,20 +647,16 @@ _ReadByte(ArchiveHandle *AH)
*
* Called by the archiver to write a block of bytes to the archive.
*/
static size_t
static void
_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
{
lclContext *ctx = (lclContext *) AH->formatData;
size_t res;
res = fwrite(buf, 1, len, AH->FH);
if (fwrite(buf, 1, len, AH->FH) != len)
WRITE_ERROR_EXIT;
ctx->filePos += len;
if (res != len)
exit_horribly(modulename,
"could not write to output file: %s\n", strerror(errno));
ctx->filePos += res;
return res;
return;
}
/*
@ -671,16 +666,16 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
*
* Called by the archiver to read a block of bytes from the archive
*/
static size_t
static void
_ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
{
lclContext *ctx = (lclContext *) AH->formatData;
size_t res;
res = fread(buf, 1, len, AH->FH);
ctx->filePos += res;
if (fread(buf, 1, len, AH->FH) != len)
READ_ERROR_EXIT(AH->FH);
ctx->filePos += len;
return res;
return;
}
/*
@ -959,15 +954,16 @@ _readBlockHeader(ArchiveHandle *AH, int *type, int *id)
* Callback function for WriteDataToArchive. Writes one block of (compressed)
* data to the archive.
*/
static size_t
static void
_CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len)
{
/* never write 0-byte blocks (this should not happen) */
if (len == 0)
return 0;
WriteInt(AH, len);
return _WriteBuf(AH, buf, len);
if (len > 0)
{
WriteInt(AH, len);
_WriteBuf(AH, buf, len);
}
return;
}
/*
@ -978,7 +974,6 @@ static size_t
_CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
{
size_t blkLen;
size_t cnt;
/* Read length */
blkLen = ReadInt(AH);
@ -993,15 +988,8 @@ _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
*buflen = blkLen;
}
cnt = _ReadBuf(AH, *buf, blkLen);
if (cnt != blkLen)
{
if (feof(AH->FH))
exit_horribly(modulename,
"could not read from input file: end of file\n");
else
exit_horribly(modulename,
"could not read from input file: %s\n", strerror(errno));
}
return cnt;
/* exits app on read errors */
_ReadBuf(AH, *buf, blkLen);
return blkLen;
}