]> granicus.if.org Git - postgresql/commitdiff
Properly detect read and write errors in pg_dump/dumpall, and pg_restore
authorBruce Momjian <bruce@momjian.us>
Tue, 6 May 2014 00:27:16 +0000 (20:27 -0400)
committerBruce Momjian <bruce@momjian.us>
Tue, 6 May 2014 00:27:16 +0000 (20:27 -0400)
Previously some I/O errors were ignored.

src/bin/pg_dump/compress_io.c
src/bin/pg_dump/compress_io.h
src/bin/pg_dump/pg_backup.h
src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_backup_archiver.h
src/bin/pg_dump/pg_backup_custom.c
src/bin/pg_dump/pg_backup_db.c
src/bin/pg_dump/pg_backup_directory.c
src/bin/pg_dump/pg_backup_null.c
src/bin/pg_dump/pg_backup_tar.c

index 10bc3f048daf7a52a836eaa7b8bf336d8f127a48..06056b1c34452e6da2d8c19e19d8ec7066f0e603 100644 (file)
@@ -86,14 +86,14 @@ static void InitCompressorZlib(CompressorState *cs, int level);
 static void DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs,
                                          bool flush);
 static void ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF);
-static size_t WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
+static void WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
                                           const char *data, size_t dLen);
 static void EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs);
 #endif
 
 /* Routines that support uncompressed data I/O */
 static void ReadDataFromArchiveNone(ArchiveHandle *AH, ReadFunc readF);
-static size_t WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
+static void WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
                                           const char *data, size_t dLen);
 
 /*
@@ -179,7 +179,7 @@ ReadDataFromArchive(ArchiveHandle *AH, int compression, ReadFunc readF)
 /*
  * Compress and write data to the output stream (via writeF).
  */
-size_t
+void
 WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
                                   const void *data, size_t dLen)
 {
@@ -190,14 +190,16 @@ WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
        {
                case COMPR_ALG_LIBZ:
 #ifdef HAVE_LIBZ
-                       return WriteDataToArchiveZlib(AH, cs, data, dLen);
+                       WriteDataToArchiveZlib(AH, cs, data, dLen);
 #else
                        exit_horribly(modulename, "not built with zlib support\n");
 #endif
+                       break;
                case COMPR_ALG_NONE:
-                       return WriteDataToArchiveNone(AH, cs, data, dLen);
+                       WriteDataToArchiveNone(AH, cs, data, dLen);
+                       break;
        }
-       return 0;                                       /* keep compiler quiet */
+       return;
 }
 
 /*
@@ -298,10 +300,7 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
                                 */
                                size_t          len = cs->zlibOutSize - zp->avail_out;
 
-                               if (cs->writeF(AH, out, len) != len)
-                                       exit_horribly(modulename,
-                                                                 "could not write to output file: %s\n",
-                                                                 strerror(errno));
+                               cs->writeF(AH, out, len);
                        }
                        zp->next_out = (void *) out;
                        zp->avail_out = cs->zlibOutSize;
@@ -312,7 +311,7 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
        }
 }
 
-static size_t
+static void
 WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
                                           const char *data, size_t dLen)
 {
@@ -320,11 +319,7 @@ WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
        cs->zp->avail_in = dLen;
        DeflateCompressorZlib(AH, cs, false);
 
-       /*
-        * we have either succeeded in writing dLen bytes or we have called
-        * exit_horribly()
-        */
-       return dLen;
+       return;
 }
 
 static void
@@ -427,19 +422,12 @@ ReadDataFromArchiveNone(ArchiveHandle *AH, ReadFunc readF)
        free(buf);
 }
 
-static size_t
+static void
 WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
                                           const char *data, size_t dLen)
 {
-       /*
-        * Any write function should do its own error checking but to make sure we
-        * do a check here as well...
-        */
-       if (cs->writeF(AH, data, dLen) != dLen)
-               exit_horribly(modulename,
-                                         "could not write to output file: %s\n",
-                                         strerror(errno));
-       return dLen;
+       cs->writeF(AH, data, dLen);
+       return;
 }
 
 
@@ -573,12 +561,27 @@ cfopen(const char *path, const char *mode, int compression)
 int
 cfread(void *ptr, int size, cfp *fp)
 {
+       int ret;
+
+       if (size == 0)
+               return 0;
+
 #ifdef HAVE_LIBZ
        if (fp->compressedfp)
-               return gzread(fp->compressedfp, ptr, size);
+       {
+               ret = gzread(fp->compressedfp, ptr, size);
+               if (ret != size && !gzeof(fp->compressedfp))
+                       exit_horribly(modulename,
+                                       "could not read from input file: %s\n", strerror(errno));
+       }
        else
 #endif
-               return fread(ptr, 1, size, fp->uncompressedfp);
+       {
+               ret = fread(ptr, 1, size, fp->uncompressedfp);
+               if (ret != size && !feof(fp->uncompressedfp))
+                       READ_ERROR_EXIT(fp->uncompressedfp);
+       }
+       return ret;
 }
 
 int
@@ -595,12 +598,31 @@ cfwrite(const void *ptr, int size, cfp *fp)
 int
 cfgetc(cfp *fp)
 {
+       int ret;
+
 #ifdef HAVE_LIBZ
        if (fp->compressedfp)
-               return gzgetc(fp->compressedfp);
+       {
+               ret = gzgetc(fp->compressedfp);
+               if (ret == EOF)
+               {
+                       if (!gzeof(fp->compressedfp))
+                               exit_horribly(modulename,
+                                               "could not read from input file: %s\n", strerror(errno));
+                       else
+                               exit_horribly(modulename,
+                                               "could not read from input file: end of file\n");
+               }
+       }
        else
 #endif
-               return fgetc(fp->uncompressedfp);
+       {
+               ret = fgetc(fp->uncompressedfp);
+               if (ret == EOF)
+                       READ_ERROR_EXIT(fp->uncompressedfp);
+       }
+
+       return ret;
 }
 
 char *
index aecfba5937197e2c5c3ff9f0de4ba21cb8fd2a7b..713c78b8a79dde476b8f886fc69183a4490fda20 100644 (file)
@@ -29,7 +29,7 @@ typedef enum
 } CompressionAlgorithm;
 
 /* Prototype for callback function to WriteDataToArchive() */
-typedef size_t (*WriteFunc) (ArchiveHandle *AH, const char *buf, size_t len);
+typedef void (*WriteFunc) (ArchiveHandle *AH, const char *buf, size_t len);
 
 /*
  * Prototype for callback function to ReadDataFromArchive()
@@ -50,7 +50,7 @@ typedef struct CompressorState CompressorState;
 extern CompressorState *AllocateCompressor(int compression, WriteFunc writeF);
 extern void ReadDataFromArchive(ArchiveHandle *AH, int compression,
                                        ReadFunc readF);
-extern size_t WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
+extern void WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
                                   const void *data, size_t dLen);
 extern void EndCompressor(ArchiveHandle *AH, CompressorState *cs);
 
index 83f7216d50e6a66d557854a9f213325d16f703e1..08ace67db4ba379bc8dfc0085afb2570316e063c 100644 (file)
@@ -180,7 +180,7 @@ extern void ArchiveEntry(Archive *AHX,
                         DataDumperPtr dumpFn, void *dumpArg);
 
 /* Called to write *data* to the archive */
-extern size_t WriteData(Archive *AH, const void *data, size_t dLen);
+extern void WriteData(Archive *AH, const void *data, size_t dLen);
 
 extern int     StartBlob(Archive *AH, Oid oid);
 extern int     EndBlob(Archive *AH, Oid oid);
@@ -208,7 +208,7 @@ extern RestoreOptions *NewRestoreOptions(void);
 extern void SortTocFromFile(Archive *AHX, RestoreOptions *ropt);
 
 /* Convenience functions used only when writing DATA */
-extern int     archputs(const char *s, Archive *AH);
+extern void    archputs(const char *s, Archive *AH);
 extern int
 archprintf(Archive *AH, const char *fmt,...)
 /* This extension allows gcc to check the format string */
index 946454019bd533471275b5e556b941b0cdc11838..adf91e1697c9b91f2e1b559b9ab286eb80d61903 100644 (file)
@@ -855,7 +855,7 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt
  */
 
 /* Public */
-size_t
+void
 WriteData(Archive *AHX, const void *data, size_t dLen)
 {
        ArchiveHandle *AH = (ArchiveHandle *) AHX;
@@ -863,7 +863,9 @@ WriteData(Archive *AHX, const void *data, size_t dLen)
        if (!AH->currToc)
                exit_horribly(modulename, "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n");
 
-       return (*AH->WriteDataPtr) (AH, data, dLen);
+       (*AH->WriteDataPtr) (AH, data, dLen);
+
+       return;
 }
 
 /*
@@ -1246,10 +1248,11 @@ SortTocFromFile(Archive *AHX, RestoreOptions *ropt)
  **********************/
 
 /* Public */
-int
+void
 archputs(const char *s, Archive *AH)
 {
-       return WriteData(AH, s, strlen(s));
+       WriteData(AH, s, strlen(s));
+       return;
 }
 
 /* Public */
@@ -1486,11 +1489,11 @@ dump_lo_buf(ArchiveHandle *AH)
  *     format to create a custom output routine to 'fake' a restore if it
  *     wants to generate a script (see TAR output).
  */
-int
+void
 ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
 {
-       size_t          res;
-
+       int bytes_written = 0;
+       
        if (AH->writingBlob)
        {
                size_t          remaining = size * nmemb;
@@ -1509,23 +1512,12 @@ ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
                memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
                AH->lo_buf_used += remaining;
 
-               return size * nmemb;
+               bytes_written = size * nmemb;
        }
        else if (AH->gzOut)
-       {
-               res = GZWRITE(ptr, size, nmemb, AH->OF);
-               if (res != (nmemb * size))
-                       exit_horribly(modulename, "could not write to output file: %s\n", strerror(errno));
-               return res;
-       }
+               bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
        else if (AH->CustomOutPtr)
-       {
-               res = AH->CustomOutPtr (AH, ptr, size * nmemb);
-
-               if (res != (nmemb * size))
-                       exit_horribly(modulename, "could not write to custom output routine\n");
-               return res;
-       }
+               bytes_written = AH->CustomOutPtr (AH, ptr, size * nmemb);
        else
        {
                /*
@@ -1533,16 +1525,15 @@ ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
                 * connected then send it to the DB.
                 */
                if (RestoringToDB(AH))
-                       return ExecuteSqlCommandBuf(AH, (const char *) ptr, size * nmemb);
+                       bytes_written  = ExecuteSqlCommandBuf(AH, (const char *) ptr, size * nmemb);
                else
-               {
-                       res = fwrite(ptr, size, nmemb, AH->OF);
-                       if (res != nmemb)
-                               exit_horribly(modulename, "could not write to output file: %s\n",
-                                                         strerror(errno));
-                       return res;
-               }
+                       bytes_written = fwrite(ptr, size, nmemb, AH->OF) * size;
        }
+
+       if (bytes_written != size * nmemb)
+               WRITE_ERROR_EXIT;
+
+       return;
 }
 
 /* on some error, we may decide to go on... */
@@ -1847,8 +1838,11 @@ WriteStr(ArchiveHandle *AH, const char *c)
 
        if (c)
        {
-               res = WriteInt(AH, strlen(c));
-               res += (*AH->WriteBufPtr) (AH, c, strlen(c));
+               int len = strlen(c);
+               
+               res = WriteInt(AH, len);
+               (*AH->WriteBufPtr) (AH, c, len);
+               res += len;
        }
        else
                res = WriteInt(AH, -1);
@@ -1868,8 +1862,7 @@ ReadStr(ArchiveHandle *AH)
        else
        {
                buf = (char *) pg_malloc(l + 1);
-               if ((*AH->ReadBufPtr) (AH, (void *) buf, l) != l)
-                       exit_horribly(modulename, "unexpected end of file\n");
+               (*AH->ReadBufPtr) (AH, (void *) buf, l);
 
                buf[l] = '\0';
        }
@@ -1950,9 +1943,7 @@ _discoverArchiveFormat(ArchiveHandle *AH)
                                                  strerror(errno));
        }
 
-       cnt = fread(sig, 1, 5, fh);
-
-       if (cnt != 5)
+       if ((cnt = fread(sig, 1, 5, fh)) != 5)
        {
                if (ferror(fh))
                        exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
@@ -1975,12 +1966,12 @@ _discoverArchiveFormat(ArchiveHandle *AH)
                 * NB: this code must agree with ReadHead().
                 */
                if ((byteread = fgetc(fh)) == EOF)
-                       exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
+                       READ_ERROR_EXIT(fh);
 
                AH->vmaj = byteread;
 
                if ((byteread = fgetc(fh)) == EOF)
-                       exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
+                       READ_ERROR_EXIT(fh);
 
                AH->vmin = byteread;
 
@@ -1992,7 +1983,7 @@ _discoverArchiveFormat(ArchiveHandle *AH)
                if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0)))                /* Version > 1.0 */
                {
                        if ((byteread = fgetc(fh)) == EOF)
-                               exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
+                               READ_ERROR_EXIT(fh);
 
                        AH->vrev = byteread;
                        AH->lookahead[AH->lookaheadLen++] = AH->vrev;
@@ -2004,20 +1995,20 @@ _discoverArchiveFormat(ArchiveHandle *AH)
                AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
 
                if ((AH->intSize = fgetc(fh)) == EOF)
-                       exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
+                       READ_ERROR_EXIT(fh);
                AH->lookahead[AH->lookaheadLen++] = AH->intSize;
 
                if (AH->version >= K_VERS_1_7)
                {
                        if ((AH->offSize = fgetc(fh)) == EOF)
-                               exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
+                               READ_ERROR_EXIT(fh);
                        AH->lookahead[AH->lookaheadLen++] = AH->offSize;
                }
                else
                        AH->offSize = AH->intSize;
 
                if ((byteread = fgetc(fh)) == EOF)
-                       exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
+                       READ_ERROR_EXIT(fh);
 
                AH->format = byteread;
                AH->lookahead[AH->lookaheadLen++] = AH->format;
@@ -2029,6 +2020,7 @@ _discoverArchiveFormat(ArchiveHandle *AH)
                 * read first 512 byte header...
                 */
                cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
+               /* read failure is checked below */
                AH->lookaheadLen += cnt;
 
                if (AH->lookaheadLen >= strlen(TEXT_DUMPALL_HEADER) &&
@@ -2042,8 +2034,10 @@ _discoverArchiveFormat(ArchiveHandle *AH)
                        exit_horribly(modulename, "input file appears to be a text format dump. Please use psql.\n");
                }
 
-               if (AH->lookaheadLen != 512)
+               if (AH->lookaheadLen != 512 && feof(fh))
                        exit_horribly(modulename, "input file does not appear to be a valid archive (too short?)\n");
+               else
+                       READ_ERROR_EXIT(fh);
 
                if (!isValidTarHeader(AH->lookahead))
                        exit_horribly(modulename, "input file does not appear to be a valid archive\n");
@@ -3318,8 +3312,7 @@ ReadHead(ArchiveHandle *AH)
         */
        if (!AH->readHeader)
        {
-               if ((*AH->ReadBufPtr) (AH, tmpMag, 5) != 5)
-                       exit_horribly(modulename, "unexpected end of file\n");
+               (*AH->ReadBufPtr) (AH, tmpMag, 5);
 
                if (strncmp(tmpMag, "PGDMP", 5) != 0)
                        exit_horribly(modulename, "did not find magic string in file header\n");
index 25aa158e5daf464b021ca549ed71b45e89f1a735..92ec1d89c6c76dbf074658551d8f7e0dd7a064c3 100644 (file)
 #define GZCLOSE(fh) gzclose(fh)
 #define GZWRITE(p, s, n, fh) gzwrite(fh, p, (n) * (s))
 #define GZREAD(p, s, n, fh) gzread(fh, p, (n) * (s))
+#define GZEOF(fh)      gzeof(fh)
 #else
 #define GZCLOSE(fh) fclose(fh)
 #define GZWRITE(p, s, n, fh) (fwrite(p, s, n, fh) * (s))
 #define GZREAD(p, s, n, fh) fread(p, s, n, fh)
+#define GZEOF(fh)      feof(fh)
 /* this is just the redefinition of a libz constant */
 #define Z_DEFAULT_COMPRESSION (-1)
 
@@ -115,6 +117,22 @@ struct _restoreList;
 struct ParallelArgs;
 struct ParallelState;
 
+#define READ_ERROR_EXIT(fd) \
+       do { \
+               if (feof(fd)) \
+                       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)); \
+       } while (0)
+
+#define WRITE_ERROR_EXIT \
+       do { \
+               exit_horribly(modulename, "could not write to output file: %s\n", \
+                                         strerror(errno)); \
+       } while (0)
 typedef enum T_Action
 {
        ACT_DUMP,
@@ -126,7 +144,7 @@ typedef void (*ReopenPtr) (struct _archiveHandle * AH);
 typedef void (*ArchiveEntryPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
 
 typedef void (*StartDataPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
-typedef size_t (*WriteDataPtr) (struct _archiveHandle * AH, const void *data, size_t dLen);
+typedef void (*WriteDataPtr) (struct _archiveHandle * AH, const void *data, size_t dLen);
 typedef void (*EndDataPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
 
 typedef void (*StartBlobsPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
@@ -136,8 +154,8 @@ typedef void (*EndBlobsPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
 
 typedef int (*WriteBytePtr) (struct _archiveHandle * AH, const int i);
 typedef int (*ReadBytePtr) (struct _archiveHandle * AH);
-typedef size_t (*WriteBufPtr) (struct _archiveHandle * AH, const void *c, size_t len);
-typedef size_t (*ReadBufPtr) (struct _archiveHandle * AH, void *buf, size_t len);
+typedef void (*WriteBufPtr) (struct _archiveHandle * AH, const void *c, size_t len);
+typedef void (*ReadBufPtr) (struct _archiveHandle * AH, void *buf, size_t len);
 typedef void (*SaveArchivePtr) (struct _archiveHandle * AH);
 typedef void (*WriteExtraTocPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
 typedef void (*ReadExtraTocPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
@@ -413,7 +431,7 @@ extern bool isValidTarHeader(char *header);
 extern int     ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser);
 extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid);
 
-int                    ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH);
+void           ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH);
 int                    ahprintf(ArchiveHandle *AH, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
 
 void           ahlog(ArchiveHandle *AH, int level, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
index de4f023fa748b37306753f83f6d07c4d164c89e3..5f3a9100896fd1c3f10d5b6baefd8184f1890cb8 100644 (file)
 
 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;
 }
index cd2ddedada47205bb49f77c445e3d46276fb6617..980d68fdabd44d4857a9fcca1f36fe6ab927f0fe 100644 (file)
@@ -540,7 +540,7 @@ ExecuteSqlCommandBuf(ArchiveHandle *AH, const char *buf, size_t bufLen)
                }
        }
 
-       return 1;
+       return bufLen;
 }
 
 /*
index 0fae53b3468f2be38c956686ad7e709fe867f80a..2cd9b7e9f8ea138474a09b0397a4518ace648dc4 100644 (file)
@@ -66,11 +66,11 @@ static const char *modulename = gettext_noop("directory archiver");
 static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
 static void _StartData(ArchiveHandle *AH, TocEntry *te);
 static void _EndData(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 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);
@@ -350,18 +350,18 @@ _StartData(ArchiveHandle *AH, TocEntry *te)
  *
  * We write the data to the open data file.
  */
-static size_t
+static void
 _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
 {
        lclContext *ctx = (lclContext *) AH->formatData;
 
-       if (dLen == 0)
-               return 0;
-
        /* Are we aborting? */
        checkAborting(AH);
+       
+       if (dLen > 0 && cfwrite(data, dLen, ctx->dataFH) != dLen)
+               WRITE_ERROR_EXIT;
 
-       return cfwrite(data, dLen, ctx->dataFH);
+       return;
 }
 
 /*
@@ -408,7 +408,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt)
                ahwrite(buf, 1, cnt, AH);
 
        free(buf);
-       if (cfclose(cfp) !=0)
+       if (cfclose(cfp) != 0)
                exit_horribly(modulename, "could not close data file: %s\n",
                                          strerror(errno));
 }
@@ -495,7 +495,7 @@ _WriteByte(ArchiveHandle *AH, const int i)
        lclContext *ctx = (lclContext *) AH->formatData;
 
        if (cfwrite(&c, 1, ctx->dataFH) != 1)
-               exit_horribly(modulename, "could not write byte\n");
+               WRITE_ERROR_EXIT;
 
        return 1;
 }
@@ -510,34 +510,26 @@ static int
 _ReadByte(ArchiveHandle *AH)
 {
        lclContext *ctx = (lclContext *) AH->formatData;
-       int                     res;
 
-       res = cfgetc(ctx->dataFH);
-       if (res == EOF)
-               exit_horribly(modulename, "unexpected end of file\n");
-
-       return res;
+       return cfgetc(ctx->dataFH);
 }
 
 /*
  * Write a buffer of data to the archive.
  * Called by the archiver to write a block of bytes to the TOC or a data file.
  */
-static size_t
+static void
 _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
 {
        lclContext *ctx = (lclContext *) AH->formatData;
-       size_t          res;
 
        /* Are we aborting? */
        checkAborting(AH);
 
-       res = cfwrite(buf, len, ctx->dataFH);
-       if (res != len)
-               exit_horribly(modulename, "could not write to output file: %s\n",
-                                         strerror(errno));
+       if (cfwrite(buf, len, ctx->dataFH) != len)
+               WRITE_ERROR_EXIT;
 
-       return res;
+       return;
 }
 
 /*
@@ -545,15 +537,20 @@ _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 = cfread(buf, len, ctx->dataFH);
+       /*
+        * If there was an I/O error, we already exited in cfread(),
+        * so here we exit on short reads.
+        */
+       if (cfread(buf, len, ctx->dataFH) != len)
+               exit_horribly(modulename,
+                                         "could not read from input file: end of file\n");
 
-       return res;
+       return;
 }
 
 /*
index c321068b4efadaa617fbcf427dd94b6f44cc3496..3bce5885d09fb6ff150ba9f1221a35435ec4585b 100644 (file)
 
 #include "libpq/libpq-fs.h"
 
-
-static size_t _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
-static size_t _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen);
+static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
+static void _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen);
 static void _EndData(ArchiveHandle *AH, TocEntry *te);
 static int     _WriteByte(ArchiveHandle *AH, const int i);
-static size_t _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
+static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
 static void _CloseArchive(ArchiveHandle *AH);
 static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
 static void _StartBlobs(ArchiveHandle *AH, TocEntry *te);
@@ -84,19 +83,19 @@ InitArchiveFmt_Null(ArchiveHandle *AH)
 /*
  * Called by dumper via archiver from within a data dump routine
  */
-static size_t
+static void
 _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
 {
-       /* Just send it to output */
+       /* Just send it to output, ahwrite() already errors on failure */
        ahwrite(data, 1, dLen, AH);
-       return dLen;
+       return;
 }
 
 /*
  * Called by dumper via archiver from within a data dump routine
  * We substitute this for _WriteData while emitting a BLOB
  */
-static size_t
+static void
 _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
 {
        if (dLen > 0)
@@ -112,7 +111,7 @@ _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
 
                destroyPQExpBuffer(buf);
        }
-       return dLen;
+       return;
 }
 
 static void
@@ -220,11 +219,11 @@ _WriteByte(ArchiveHandle *AH, const int i)
        return 0;
 }
 
-static size_t
+static void
 _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
 {
        /* Don't do anything */
-       return len;
+       return;
 }
 
 static void
index 3bdbf868189aacada76f5a842825c51c83f8b932..f50539305714187cef0f81a751034cba23ba3ed4 100644 (file)
 
 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 _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
 static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te);
@@ -548,13 +548,26 @@ _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh)
        if (len > 0)
        {
                if (fh)
+               {
                        res = fread(&((char *) buf)[used], 1, len, fh);
+                       if (res != len && !feof(fh))
+                               READ_ERROR_EXIT(fh);
+               }
                else if (th)
                {
                        if (th->zFH)
+                       {
                                res = GZREAD(&((char *) buf)[used], 1, len, th->zFH);
+                               if (res != len && !GZEOF(fh))
+                                       exit_horribly(modulename,
+                                                       "could not read from input file: %s\n", strerror(errno));
+                       }
                        else
+                       {
                                res = fread(&((char *) buf)[used], 1, len, th->nFH);
+                               if (res != len && !feof(fh))
+                                       READ_ERROR_EXIT(fh);
+                       }
                }
                else
                        exit_horribly(modulename, "internal error -- neither th nor fh specified in tarReadRaw()\n");
@@ -593,22 +606,19 @@ tarWrite(const void *buf, size_t len, TAR_MEMBER *th)
        else
                res = fwrite(buf, 1, len, th->nFH);
 
-       if (res != len)
-               exit_horribly(modulename,
-                                       "could not write to output file: %s\n", strerror(errno));
-
        th->pos += res;
        return res;
 }
 
-static size_t
+static void
 _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
 {
        lclTocEntry *tctx = (lclTocEntry *) AH->currToc->formatData;
 
-       dLen = tarWrite(data, dLen, tctx->TH);
+       if (tarWrite(data, dLen, tctx->TH) != dLen)
+               WRITE_ERROR_EXIT;
 
-       return dLen;
+       return;
 }
 
 static void
@@ -766,13 +776,13 @@ static int
 _WriteByte(ArchiveHandle *AH, const int i)
 {
        lclContext *ctx = (lclContext *) AH->formatData;
-       int                     res;
        char            b = i;                  /* Avoid endian problems */
 
-       res = tarWrite(&b, 1, ctx->FH);
-       if (res != EOF)
-               ctx->filePos += res;
-       return res;
+       if (tarWrite(&b, 1, ctx->FH) != 1)
+               WRITE_ERROR_EXIT;
+
+       ctx->filePos += 1;
+       return 1;
 }
 
 static int
@@ -784,31 +794,36 @@ _ReadByte(ArchiveHandle *AH)
 
        res = tarRead(&c, 1, ctx->FH);
        if (res != 1)
-               exit_horribly(modulename, "unexpected end of file\n");
+               /* We already would have exited for errors on reads, must be EOF */
+               exit_horribly(modulename,
+                                         "could not read from input file: end of file\n");
        ctx->filePos += 1;
        return c;
 }
 
-static size_t
+static void
 _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
 {
        lclContext *ctx = (lclContext *) AH->formatData;
-       size_t          res;
 
-       res = tarWrite(buf, len, ctx->FH);
-       ctx->filePos += res;
-       return res;
+       if (tarWrite(buf, len, ctx->FH) != len)
+               WRITE_ERROR_EXIT;
+
+       ctx->filePos += len;
 }
 
-static size_t
+static void
 _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
 {
        lclContext *ctx = (lclContext *) AH->formatData;
-       size_t          res;
 
-       res = tarRead(buf, len, ctx->FH);
-       ctx->filePos += res;
-       return res;
+       if (tarRead(buf, len, ctx->FH) != len)
+               /* We already would have exited for errors on reads, must be EOF */
+               exit_horribly(modulename,
+                                         "could not read from input file: end of file\n");
+       
+       ctx->filePos += len;
+       return;
 }
 
 static void
@@ -885,8 +900,7 @@ _CloseArchive(ArchiveHandle *AH)
                for (i = 0; i < 512 * 2; i++)
                {
                        if (fputc(0, ctx->tarFH) == EOF)
-                               exit_horribly(modulename,
-                                          "could not write null block at end of tar archive\n");
+                               WRITE_ERROR_EXIT;
                }
        }
 
@@ -1084,13 +1098,12 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
 
        while ((cnt = fread(buf, 1, sizeof(buf), tmp)) > 0)
        {
-               res = fwrite(buf, 1, cnt, th->tarFH);
-               if (res != cnt)
-                       exit_horribly(modulename,
-                                                 "could not write to output file: %s\n",
-                                                 strerror(errno));
+               if ((res = fwrite(buf, 1, cnt, th->tarFH)) != cnt)
+                       WRITE_ERROR_EXIT;
                len += res;
        }
+       if (!feof(tmp))
+               READ_ERROR_EXIT(tmp);
 
        if (fclose(tmp) != 0)           /* This *should* delete it... */
                exit_horribly(modulename, "could not close temporary file: %s\n",
@@ -1111,7 +1124,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
        for (i = 0; i < pad; i++)
        {
                if (fputc('\0', th->tarFH) == EOF)
-                       exit_horribly(modulename, "could not output padding at end of tar member\n");
+                       WRITE_ERROR_EXIT;
        }
 
        ctx->tarFHpos += len + pad;
@@ -1294,5 +1307,5 @@ _tarWriteHeader(TAR_MEMBER *th)
 
        /* Now write the completed header. */
        if (fwrite(h, 1, 512, th->tarFH) != 512)
-               exit_horribly(modulename, "could not write to output file: %s\n", strerror(errno));
+               WRITE_ERROR_EXIT;
 }