On Sat, Mar 1, 2014 at 12:27:19PM -0800, Sean Chittenden wrote:
> The attached patch fixes the case when `pg_dump -Fd …` is called
> on a partition where write(2) fails for some reason or another. In
> this case, backup jobs were returning with a successful exit code even
> though most of the files in the dump directory were all zero length.
>
> I haven’t tested this patch’s failure conditions but the fix seems
> simple enough: cfwrite() needs to have its return status checked
> everywhere and exit_horribly() upon any failure. In this case,
> callers of _WriteData() were not checking the return status and were
> discarding the negative return status (e.g. ENOSPC).
>
> I made a cursory pass over the code and found one other instance where
> write status wasn’t being checked and also included that.

As is often the case with pg_dump, the problems you saw are a small part
of a larger set of problems in that code --- there is general ignoring of
read and write errors.

I have developed a comprehensive patch that addresses all the issues I
could find.  The use of function pointers and the calling of functions
directly and through function pointers makes the fix quite complex.  I
ended up placing checks at the lowest level and removing checks at
higher layers where they were sporadically placed.  

Patch attached.  I have tested dump/restore of all four dump output
formats with the 9.3 regression database and all tests passed.  I
believe this patch is too complex to backpatch, and I don't know how it
could be fixed more simply.

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + Everyone has their own god. +
diff --git a/src/bin/pg_dump/compress_io.c b/src/bin/pg_dump/compress_io.c
new file mode 100644
index 10bc3f0..bad21b5
*** a/src/bin/pg_dump/compress_io.c
--- b/src/bin/pg_dump/compress_io.c
*************** static void InitCompressorZlib(Compresso
*** 86,99 ****
  static void DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs,
  					  bool flush);
  static void ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF);
! static size_t 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,
  					   const char *data, size_t dLen);
  
  /*
--- 86,99 ----
  static void DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs,
  					  bool flush);
  static void ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF);
! 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 void WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
  					   const char *data, size_t dLen);
  
  /*
*************** ReadDataFromArchive(ArchiveHandle *AH, i
*** 179,185 ****
  /*
   * Compress and write data to the output stream (via writeF).
   */
! size_t
  WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
  				   const void *data, size_t dLen)
  {
--- 179,185 ----
  /*
   * Compress and write data to the output stream (via writeF).
   */
! void
  WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
  				   const void *data, size_t dLen)
  {
*************** WriteDataToArchive(ArchiveHandle *AH, Co
*** 190,203 ****
  	{
  		case COMPR_ALG_LIBZ:
  #ifdef HAVE_LIBZ
! 			return WriteDataToArchiveZlib(AH, cs, data, dLen);
  #else
  			exit_horribly(modulename, "not built with zlib support\n");
  #endif
  		case COMPR_ALG_NONE:
! 			return WriteDataToArchiveNone(AH, cs, data, dLen);
  	}
! 	return 0;					/* keep compiler quiet */
  }
  
  /*
--- 190,205 ----
  	{
  		case COMPR_ALG_LIBZ:
  #ifdef HAVE_LIBZ
! 			WriteDataToArchiveZlib(AH, cs, data, dLen);
  #else
  			exit_horribly(modulename, "not built with zlib support\n");
  #endif
+ 			break;
  		case COMPR_ALG_NONE:
! 			WriteDataToArchiveNone(AH, cs, data, dLen);
! 			break;
  	}
! 	return;
  }
  
  /*
*************** DeflateCompressorZlib(ArchiveHandle *AH,
*** 298,307 ****
  				 */
  				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));
  			}
  			zp->next_out = (void *) out;
  			zp->avail_out = cs->zlibOutSize;
--- 300,306 ----
  				 */
  				size_t		len = cs->zlibOutSize - zp->avail_out;
  
! 				cs->writeF(AH, out, len);
  			}
  			zp->next_out = (void *) out;
  			zp->avail_out = cs->zlibOutSize;
*************** DeflateCompressorZlib(ArchiveHandle *AH,
*** 312,318 ****
  	}
  }
  
! static size_t
  WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
  					   const char *data, size_t dLen)
  {
--- 311,317 ----
  	}
  }
  
! static void
  WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
  					   const char *data, size_t dLen)
  {
*************** WriteDataToArchiveZlib(ArchiveHandle *AH
*** 320,330 ****
  	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;
  }
  
  static void
--- 319,325 ----
  	cs->zp->avail_in = dLen;
  	DeflateCompressorZlib(AH, cs, false);
  
! 	return;
  }
  
  static void
*************** ReadDataFromArchiveNone(ArchiveHandle *A
*** 427,445 ****
  	free(buf);
  }
  
! static size_t
  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;
  }
  
  
--- 422,433 ----
  	free(buf);
  }
  
! static void
  WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
  					   const char *data, size_t dLen)
  {
! 	cs->writeF(AH, data, dLen);
! 	return;
  }
  
  
*************** cfopen(const char *path, const char *mod
*** 573,584 ****
  int
  cfread(void *ptr, int size, cfp *fp)
  {
  #ifdef HAVE_LIBZ
  	if (fp->compressedfp)
! 		return gzread(fp->compressedfp, ptr, size);
  	else
  #endif
! 		return fread(ptr, 1, size, fp->uncompressedfp);
  }
  
  int
--- 561,587 ----
  int
  cfread(void *ptr, int size, cfp *fp)
  {
+ 	int ret;
+ 
+ 	if (size == 0)
+ 		return 0;
+ 
  #ifdef HAVE_LIBZ
  	if (fp->compressedfp)
! 	{
! 		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
! 	{
! 		ret = fread(ptr, 1, size, fp->uncompressedfp);
! 		if (ret != size && !feof(fp->uncompressedfp))
! 			READ_ERROR_EXIT(fp->uncompressedfp);
! 	}
! 	return ret;
  }
  
  int
diff --git a/src/bin/pg_dump/compress_io.h b/src/bin/pg_dump/compress_io.h
new file mode 100644
index aecfba5..713c78b
*** a/src/bin/pg_dump/compress_io.h
--- b/src/bin/pg_dump/compress_io.h
*************** typedef enum
*** 29,35 ****
  } CompressionAlgorithm;
  
  /* Prototype for callback function to WriteDataToArchive() */
! typedef size_t (*WriteFunc) (ArchiveHandle *AH, const char *buf, size_t len);
  
  /*
   * Prototype for callback function to ReadDataFromArchive()
--- 29,35 ----
  } CompressionAlgorithm;
  
  /* Prototype for callback function to WriteDataToArchive() */
! typedef void (*WriteFunc) (ArchiveHandle *AH, const char *buf, size_t len);
  
  /*
   * Prototype for callback function to ReadDataFromArchive()
*************** typedef struct CompressorState Compresso
*** 50,56 ****
  extern CompressorState *AllocateCompressor(int compression, WriteFunc writeF);
  extern void ReadDataFromArchive(ArchiveHandle *AH, int compression,
  					ReadFunc readF);
! extern size_t WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
  				   const void *data, size_t dLen);
  extern void EndCompressor(ArchiveHandle *AH, CompressorState *cs);
  
--- 50,56 ----
  extern CompressorState *AllocateCompressor(int compression, WriteFunc writeF);
  extern void ReadDataFromArchive(ArchiveHandle *AH, int compression,
  					ReadFunc readF);
! extern void WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
  				   const void *data, size_t dLen);
  extern void EndCompressor(ArchiveHandle *AH, CompressorState *cs);
  
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
new file mode 100644
index 83f7216..08ace67
*** a/src/bin/pg_dump/pg_backup.h
--- b/src/bin/pg_dump/pg_backup.h
*************** extern void ArchiveEntry(Archive *AHX,
*** 180,186 ****
  			 DataDumperPtr dumpFn, void *dumpArg);
  
  /* Called to write *data* to the archive */
! extern size_t WriteData(Archive *AH, const void *data, size_t dLen);
  
  extern int	StartBlob(Archive *AH, Oid oid);
  extern int	EndBlob(Archive *AH, Oid oid);
--- 180,186 ----
  			 DataDumperPtr dumpFn, void *dumpArg);
  
  /* Called to write *data* to the archive */
! 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);
*************** extern RestoreOptions *NewRestoreOptions
*** 208,214 ****
  extern void SortTocFromFile(Archive *AHX, RestoreOptions *ropt);
  
  /* Convenience functions used only when writing DATA */
! extern int	archputs(const char *s, Archive *AH);
  extern int
  archprintf(Archive *AH, const char *fmt,...)
  /* This extension allows gcc to check the format string */
--- 208,214 ----
  extern void SortTocFromFile(Archive *AHX, RestoreOptions *ropt);
  
  /* Convenience functions used only when writing DATA */
! 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 */
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
new file mode 100644
index 9464540..566f29b
*** a/src/bin/pg_dump/pg_backup_archiver.c
--- b/src/bin/pg_dump/pg_backup_archiver.c
*************** _enableTriggersIfNecessary(ArchiveHandle
*** 855,861 ****
   */
  
  /* Public */
! size_t
  WriteData(Archive *AHX, const void *data, size_t dLen)
  {
  	ArchiveHandle *AH = (ArchiveHandle *) AHX;
--- 855,861 ----
   */
  
  /* Public */
! void
  WriteData(Archive *AHX, const void *data, size_t dLen)
  {
  	ArchiveHandle *AH = (ArchiveHandle *) AHX;
*************** WriteData(Archive *AHX, const void *data
*** 863,869 ****
  	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);
  }
  
  /*
--- 863,871 ----
  	if (!AH->currToc)
  		exit_horribly(modulename, "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n");
  
! 	(*AH->WriteDataPtr) (AH, data, dLen);
! 
! 	return;
  }
  
  /*
*************** SortTocFromFile(Archive *AHX, RestoreOpt
*** 1246,1255 ****
   **********************/
  
  /* Public */
! int
  archputs(const char *s, Archive *AH)
  {
! 	return WriteData(AH, s, strlen(s));
  }
  
  /* Public */
--- 1248,1258 ----
   **********************/
  
  /* Public */
! void
  archputs(const char *s, Archive *AH)
  {
! 	WriteData(AH, s, strlen(s));
! 	return;
  }
  
  /* Public */
*************** dump_lo_buf(ArchiveHandle *AH)
*** 1486,1496 ****
   *	format to create a custom output routine to 'fake' a restore if it
   *	wants to generate a script (see TAR output).
   */
! int
  ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
  {
! 	size_t		res;
! 
  	if (AH->writingBlob)
  	{
  		size_t		remaining = size * nmemb;
--- 1489,1499 ----
   *	format to create a custom output routine to 'fake' a restore if it
   *	wants to generate a script (see TAR output).
   */
! void
  ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
  {
! 	int bytes_written = 0;
! 	
  	if (AH->writingBlob)
  	{
  		size_t		remaining = size * nmemb;
*************** ahwrite(const void *ptr, size_t size, si
*** 1509,1531 ****
  		memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
  		AH->lo_buf_used += remaining;
  
! 		return 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;
! 	}
  	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;
! 	}
  	else
  	{
  		/*
--- 1512,1523 ----
  		memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
  		AH->lo_buf_used += remaining;
  
! 		bytes_written = size * nmemb;
  	}
  	else if (AH->gzOut)
! 		bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
  	else if (AH->CustomOutPtr)
! 		bytes_written = AH->CustomOutPtr (AH, ptr, size * nmemb);
  	else
  	{
  		/*
*************** ahwrite(const void *ptr, size_t size, si
*** 1533,1548 ****
  		 * connected then send it to the DB.
  		 */
  		if (RestoringToDB(AH))
! 			return 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;
! 		}
  	}
  }
  
  /* on some error, we may decide to go on... */
--- 1525,1539 ----
  		 * connected then send it to the DB.
  		 */
  		if (RestoringToDB(AH))
! 			bytes_written  = ExecuteSqlCommandBuf(AH, (const char *) ptr, size * nmemb);
  		else
! 			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... */
*************** WriteStr(ArchiveHandle *AH, const char *
*** 1847,1854 ****
  
  	if (c)
  	{
! 		res = WriteInt(AH, strlen(c));
! 		res += (*AH->WriteBufPtr) (AH, c, strlen(c));
  	}
  	else
  		res = WriteInt(AH, -1);
--- 1838,1848 ----
  
  	if (c)
  	{
! 		int len = strlen(c);
! 		
! 		res = WriteInt(AH, len);
! 		(*AH->WriteBufPtr) (AH, c, len);
! 		res += len;
  	}
  	else
  		res = WriteInt(AH, -1);
*************** ReadStr(ArchiveHandle *AH)
*** 1868,1875 ****
  	else
  	{
  		buf = (char *) pg_malloc(l + 1);
! 		if ((*AH->ReadBufPtr) (AH, (void *) buf, l) != l)
! 			exit_horribly(modulename, "unexpected end of file\n");
  
  		buf[l] = '\0';
  	}
--- 1862,1868 ----
  	else
  	{
  		buf = (char *) pg_malloc(l + 1);
! 		(*AH->ReadBufPtr) (AH, (void *) buf, l);
  
  		buf[l] = '\0';
  	}
*************** _discoverArchiveFormat(ArchiveHandle *AH
*** 2029,2034 ****
--- 2022,2029 ----
  		 * read first 512 byte header...
  		 */
  		cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
+ 		if (cnt != 512 - AH->lookaheadLen)
+ 			READ_ERROR_EXIT(fh);
  		AH->lookaheadLen += cnt;
  
  		if (AH->lookaheadLen >= strlen(TEXT_DUMPALL_HEADER) &&
*************** ReadHead(ArchiveHandle *AH)
*** 3318,3325 ****
  	 */
  	if (!AH->readHeader)
  	{
! 		if ((*AH->ReadBufPtr) (AH, tmpMag, 5) != 5)
! 			exit_horribly(modulename, "unexpected end of file\n");
  
  		if (strncmp(tmpMag, "PGDMP", 5) != 0)
  			exit_horribly(modulename, "did not find magic string in file header\n");
--- 3313,3319 ----
  	 */
  	if (!AH->readHeader)
  	{
! 		(*AH->ReadBufPtr) (AH, tmpMag, 5);
  
  		if (strncmp(tmpMag, "PGDMP", 5) != 0)
  			exit_horribly(modulename, "did not find magic string in file header\n");
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
new file mode 100644
index 25aa158..92ec1d8
*** a/src/bin/pg_dump/pg_backup_archiver.h
--- b/src/bin/pg_dump/pg_backup_archiver.h
***************
*** 45,54 ****
--- 45,56 ----
  #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)
  
*************** struct _restoreList;
*** 115,120 ****
--- 117,138 ----
  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,
*************** typedef void (*ReopenPtr) (struct _archi
*** 126,132 ****
  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 (*EndDataPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
  
  typedef void (*StartBlobsPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
--- 144,150 ----
  typedef void (*ArchiveEntryPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
  
  typedef void (*StartDataPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
! 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);
*************** typedef void (*EndBlobsPtr) (struct _arc
*** 136,143 ****
  
  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 (*SaveArchivePtr) (struct _archiveHandle * AH);
  typedef void (*WriteExtraTocPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
  typedef void (*ReadExtraTocPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
--- 154,161 ----
  
  typedef int (*WriteBytePtr) (struct _archiveHandle * AH, const int i);
  typedef int (*ReadBytePtr) (struct _archiveHandle * AH);
! 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);
*************** extern bool isValidTarHeader(char *heade
*** 413,419 ****
  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);
  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)));
--- 431,437 ----
  extern int	ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser);
  extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid);
  
! 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)));
diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c
new file mode 100644
index 72bdc39..9a8bc42
*** a/src/bin/pg_dump/pg_backup_custom.c
--- b/src/bin/pg_dump/pg_backup_custom.c
***************
*** 35,46 ****
  
  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 _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 _CloseArchive(ArchiveHandle *AH);
  static void _ReopenArchive(ArchiveHandle *AH);
  static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
--- 35,46 ----
  
  static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
  static void _StartData(ArchiveHandle *AH, TocEntry *te);
! 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 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);
*************** typedef struct
*** 86,92 ****
  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 size_t _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen);
  
  /* translator: this is a module name */
--- 86,92 ----
  static void _readBlockHeader(ArchiveHandle *AH, int *type, int *id);
  static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx);
  
! 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 */
*************** _StartData(ArchiveHandle *AH, TocEntry *
*** 315,330 ****
   *
   * Mandatory.
   */
! static size_t
  _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  	CompressorState *cs = ctx->cs;
  
! 	if (dLen == 0)
! 		return 0;
  
! 	return WriteDataToArchive(AH, cs, data, dLen);
  }
  
  /*
--- 315,331 ----
   *
   * Mandatory.
   */
! static void
  _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  	CompressorState *cs = ctx->cs;
  
! 	if (dLen > 0)
! 		/* WriteDataToArchive() internally throws write errors */
! 		WriteDataToArchive(AH, cs, data, dLen);
  
! 	return;
  }
  
  /*
*************** static int
*** 610,623 ****
  _WriteByte(ArchiveHandle *AH, const int i)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
! 	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;
  }
  
  /*
--- 611,623 ----
  _WriteByte(ArchiveHandle *AH, const int i)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
! 	int res;
  
! 	if ((res = fputc(i, AH->FH)) == EOF)
! 		WRITE_ERROR_EXIT;
! 	ctx->filePos += 1;
! 
! 	return 1;
  }
  
  /*
*************** _ReadByte(ArchiveHandle *AH)
*** 636,642 ****
  
  	res = getc(AH->FH);
  	if (res == EOF)
! 		exit_horribly(modulename, "unexpected end of file\n");
  	ctx->filePos += 1;
  	return res;
  }
--- 636,642 ----
  
  	res = getc(AH->FH);
  	if (res == EOF)
! 		READ_ERROR_EXIT(AH->FH);
  	ctx->filePos += 1;
  	return res;
  }
*************** _ReadByte(ArchiveHandle *AH)
*** 648,667 ****
   *
   * Called by the archiver to write a block of bytes to the archive.
   */
! static size_t
  _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 (res != len)
! 		exit_horribly(modulename,
! 					"could not write to output file: %s\n", strerror(errno));
  
! 	ctx->filePos += res;
! 	return res;
  }
  
  /*
--- 648,663 ----
   *
   * Called by the archiver to write a block of bytes to the archive.
   */
! static void
  _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  
! 	if (fwrite(buf, 1, len, AH->FH) != len)
! 		WRITE_ERROR_EXIT;
! 	ctx->filePos += len;
  
! 	return;
  }
  
  /*
*************** _WriteBuf(ArchiveHandle *AH, const void
*** 671,686 ****
   *
   * Called by the archiver to read a block of bytes from the archive
   */
! static size_t
  _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;
  
! 	return res;
  }
  
  /*
--- 667,682 ----
   *
   * Called by the archiver to read a block of bytes from the archive
   */
! static void
  _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  
! 	if (fread(buf, 1, len, AH->FH) != len)
! 		READ_ERROR_EXIT(AH->FH);
! 	ctx->filePos += len;
  
! 	return;
  }
  
  /*
*************** _readBlockHeader(ArchiveHandle *AH, int
*** 955,969 ****
   * Callback function for WriteDataToArchive. Writes one block of (compressed)
   * data to the archive.
   */
! static size_t
  _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);
  }
  
  /*
--- 951,966 ----
   * Callback function for WriteDataToArchive. Writes one block of (compressed)
   * data to the archive.
   */
! static void
  _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len)
  {
  	/* never write 0-byte blocks (this should not happen) */
! 	if (len > 0)
! 	{
! 		WriteInt(AH, len);
! 		_WriteBuf(AH, buf, len);
! 	}
! 	return;
  }
  
  /*
*************** static size_t
*** 974,980 ****
  _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
  {
  	size_t		blkLen;
- 	size_t		cnt;
  
  	/* Read length */
  	blkLen = ReadInt(AH);
--- 971,976 ----
*************** _CustomReadFunc(ArchiveHandle *AH, char
*** 989,1003 ****
  		*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;
  }
--- 985,992 ----
  		*buflen = blkLen;
  	}
  
! 	/* exits app on read errors */
! 	_ReadBuf(AH, *buf, blkLen);
! 
! 	return blkLen;
  }
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
new file mode 100644
index cd2dded..980d68f
*** a/src/bin/pg_dump/pg_backup_db.c
--- b/src/bin/pg_dump/pg_backup_db.c
*************** ExecuteSqlCommandBuf(ArchiveHandle *AH,
*** 540,546 ****
  		}
  	}
  
! 	return 1;
  }
  
  /*
--- 540,546 ----
  		}
  	}
  
! 	return bufLen;
  }
  
  /*
diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c
new file mode 100644
index 0fae53b..29f33de
*** a/src/bin/pg_dump/pg_backup_directory.c
--- b/src/bin/pg_dump/pg_backup_directory.c
*************** static const char *modulename = gettext_
*** 66,76 ****
  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 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 _CloseArchive(ArchiveHandle *AH);
  static void _ReopenArchive(ArchiveHandle *AH);
  static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
--- 66,76 ----
  static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
  static void _StartData(ArchiveHandle *AH, TocEntry *te);
  static void _EndData(ArchiveHandle *AH, TocEntry *te);
! static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
  static int	_WriteByte(ArchiveHandle *AH, const int i);
  static int	_ReadByte(ArchiveHandle *);
! 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);
*************** _StartData(ArchiveHandle *AH, TocEntry *
*** 350,367 ****
   *
   * We write the data to the open data file.
   */
! static size_t
  _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  
- 	if (dLen == 0)
- 		return 0;
- 
  	/* Are we aborting? */
  	checkAborting(AH);
  
! 	return cfwrite(data, dLen, ctx->dataFH);
  }
  
  /*
--- 350,367 ----
   *
   * We write the data to the open data file.
   */
! static void
  _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  
  	/* Are we aborting? */
  	checkAborting(AH);
+ 	
+ 	if (dLen > 0 && cfwrite(data, dLen, ctx->dataFH) != dLen)
+ 		WRITE_ERROR_EXIT;
  
! 	return;
  }
  
  /*
*************** _PrintFileData(ArchiveHandle *AH, char *
*** 408,414 ****
  		ahwrite(buf, 1, cnt, AH);
  
  	free(buf);
! 	if (cfclose(cfp) !=0)
  		exit_horribly(modulename, "could not close data file: %s\n",
  					  strerror(errno));
  }
--- 408,414 ----
  		ahwrite(buf, 1, cnt, AH);
  
  	free(buf);
! 	if (cfclose(cfp) != 0)
  		exit_horribly(modulename, "could not close data file: %s\n",
  					  strerror(errno));
  }
*************** _WriteByte(ArchiveHandle *AH, const int
*** 495,501 ****
  	lclContext *ctx = (lclContext *) AH->formatData;
  
  	if (cfwrite(&c, 1, ctx->dataFH) != 1)
! 		exit_horribly(modulename, "could not write byte\n");
  
  	return 1;
  }
--- 495,501 ----
  	lclContext *ctx = (lclContext *) AH->formatData;
  
  	if (cfwrite(&c, 1, ctx->dataFH) != 1)
! 		WRITE_ERROR_EXIT;
  
  	return 1;
  }
*************** _ReadByte(ArchiveHandle *AH)
*** 514,520 ****
  
  	res = cfgetc(ctx->dataFH);
  	if (res == EOF)
! 		exit_horribly(modulename, "unexpected end of file\n");
  
  	return res;
  }
--- 514,521 ----
  
  	res = cfgetc(ctx->dataFH);
  	if (res == EOF)
! 		exit_horribly(modulename,
! 					  "could not read from input file: end of file\n");
  
  	return res;
  }
*************** _ReadByte(ArchiveHandle *AH)
*** 523,543 ****
   * 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
  _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));
  
! 	return res;
  }
  
  /*
--- 524,541 ----
   * 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 void
  _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  
  	/* Are we aborting? */
  	checkAborting(AH);
  
! 	if (cfwrite(buf, len, ctx->dataFH) != len)
! 		WRITE_ERROR_EXIT;
  
! 	return;
  }
  
  /*
*************** _WriteBuf(ArchiveHandle *AH, const void
*** 545,559 ****
   *
   * Called by the archiver to read a block of bytes from the archive
   */
! static size_t
  _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
- 	size_t		res;
  
! 	res = cfread(buf, len, ctx->dataFH);
  
! 	return res;
  }
  
  /*
--- 543,562 ----
   *
   * Called by the archiver to read a block of bytes from the archive
   */
! static void
  _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  
! 	/*
! 	 * 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;
  }
  
  /*
diff --git a/src/bin/pg_dump/pg_backup_null.c b/src/bin/pg_dump/pg_backup_null.c
new file mode 100644
index c321068..3bce588
*** a/src/bin/pg_dump/pg_backup_null.c
--- b/src/bin/pg_dump/pg_backup_null.c
***************
*** 30,41 ****
  
  #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 _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 _CloseArchive(ArchiveHandle *AH);
  static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
  static void _StartBlobs(ArchiveHandle *AH, TocEntry *te);
--- 30,40 ----
  
  #include "libpq/libpq-fs.h"
  
! 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 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);
*************** InitArchiveFmt_Null(ArchiveHandle *AH)
*** 84,102 ****
  /*
   * Called by dumper via archiver from within a data dump routine
   */
! static size_t
  _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
  {
! 	/* Just send it to output */
  	ahwrite(data, 1, dLen, AH);
! 	return dLen;
  }
  
  /*
   * Called by dumper via archiver from within a data dump routine
   * We substitute this for _WriteData while emitting a BLOB
   */
! static size_t
  _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
  {
  	if (dLen > 0)
--- 83,101 ----
  /*
   * Called by dumper via archiver from within a data dump routine
   */
! static void
  _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
  {
! 	/* Just send it to output, ahwrite() already errors on failure */
  	ahwrite(data, 1, dLen, AH);
! 	return;
  }
  
  /*
   * Called by dumper via archiver from within a data dump routine
   * We substitute this for _WriteData while emitting a BLOB
   */
! static void
  _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
  {
  	if (dLen > 0)
*************** _WriteBlobData(ArchiveHandle *AH, const
*** 112,118 ****
  
  		destroyPQExpBuffer(buf);
  	}
! 	return dLen;
  }
  
  static void
--- 111,117 ----
  
  		destroyPQExpBuffer(buf);
  	}
! 	return;
  }
  
  static void
*************** _WriteByte(ArchiveHandle *AH, const int
*** 220,230 ****
  	return 0;
  }
  
! static size_t
  _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
  {
  	/* Don't do anything */
! 	return len;
  }
  
  static void
--- 219,229 ----
  	return 0;
  }
  
! static void
  _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
  {
  	/* Don't do anything */
! 	return;
  }
  
  static void
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
new file mode 100644
index 3bdbf86..b08d04f
*** a/src/bin/pg_dump/pg_backup_tar.c
--- b/src/bin/pg_dump/pg_backup_tar.c
***************
*** 42,53 ****
  
  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 _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 _CloseArchive(ArchiveHandle *AH);
  static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
  static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te);
--- 42,53 ----
  
  static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
  static void _StartData(ArchiveHandle *AH, TocEntry *te);
! 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 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);
*************** _tarReadRaw(ArchiveHandle *AH, void *buf
*** 548,560 ****
--- 548,573 ----
  	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");
*************** tarWrite(const void *buf, size_t len, TA
*** 593,614 ****
  	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
  _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
  {
  	lclTocEntry *tctx = (lclTocEntry *) AH->currToc->formatData;
  
! 	dLen = tarWrite(data, dLen, tctx->TH);
  
! 	return dLen;
  }
  
  static void
--- 606,624 ----
  	else
  		res = fwrite(buf, 1, len, th->nFH);
  
  	th->pos += res;
  	return res;
  }
  
! static void
  _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
  {
  	lclTocEntry *tctx = (lclTocEntry *) AH->currToc->formatData;
  
! 	if (tarWrite(data, dLen, tctx->TH) != dLen)
! 		WRITE_ERROR_EXIT;
  
! 	return;
  }
  
  static void
*************** static int
*** 766,778 ****
  _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;
  }
  
  static int
--- 776,788 ----
  _WriteByte(ArchiveHandle *AH, const int i)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  	char		b = i;			/* Avoid endian problems */
  
! 	if (tarWrite(&b, 1, ctx->FH) != 1)
! 		WRITE_ERROR_EXIT;
! 
! 	ctx->filePos += 1;
! 	return 1;
  }
  
  static int
*************** _ReadByte(ArchiveHandle *AH)
*** 784,814 ****
  
  	res = tarRead(&c, 1, ctx->FH);
  	if (res != 1)
! 		exit_horribly(modulename, "unexpected end of file\n");
  	ctx->filePos += 1;
  	return c;
  }
  
! static size_t
  _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;
  }
  
! static size_t
  _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;
  }
  
  static void
--- 794,829 ----
  
  	res = tarRead(&c, 1, ctx->FH);
  	if (res != 1)
! 		/* 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 void
  _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  
! 	if (tarWrite(buf, len, ctx->FH) != len)
! 		WRITE_ERROR_EXIT;
! 
! 	ctx->filePos += len;
  }
  
! static void
  _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
  {
  	lclContext *ctx = (lclContext *) AH->formatData;
  
! 	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
*************** _tarAddFile(ArchiveHandle *AH, TAR_MEMBE
*** 1084,1094 ****
  
  	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));
  		len += res;
  	}
  
--- 1099,1106 ----
  
  	while ((cnt = fread(buf, 1, sizeof(buf), tmp)) > 0)
  	{
! 		if ((res = fwrite(buf, 1, cnt, th->tarFH)) != cnt)
! 			WRITE_ERROR_EXIT;
  		len += res;
  	}
  
*************** _tarWriteHeader(TAR_MEMBER *th)
*** 1294,1298 ****
  
  	/* 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));
  }
--- 1306,1310 ----
  
  	/* Now write the completed header. */
  	if (fwrite(h, 1, 512, th->tarFH) != 512)
! 		WRITE_ERROR_EXIT;
  }
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to