Commit 9d23a70d authored by Alvaro Herrera's avatar Alvaro Herrera

pg_dump: get rid of die_horribly

The old code was using exit_horribly or die_horribly other depending on
whether it had an ArchiveHandle on which to close the connection or not;
but there were places that were passing a NULL ArchiveHandle to
die_horribly, and other places that used exit_horribly while having an
AH available.  So there wasn't all that much consistency.

Improve the situation by keeping only one of the routines, and instead
of having to pass the AH down from the caller, arrange for it to be
present for an on_exit_nicely callback to operate on.

Author: Joachim Wieland
Some tweaks by me

Per a suggestion from Robert Haas, in the ongoing "parallel pg_dump"
saga.
parent b251cf31
...@@ -256,7 +256,7 @@ EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs) ...@@ -256,7 +256,7 @@ EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs)
DeflateCompressorZlib(AH, cs, true); DeflateCompressorZlib(AH, cs, true);
if (deflateEnd(zp) != Z_OK) if (deflateEnd(zp) != Z_OK)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not close compression stream: %s\n", zp->msg); "could not close compression stream: %s\n", zp->msg);
free(cs->zlibOut); free(cs->zlibOut);
...@@ -274,7 +274,7 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush) ...@@ -274,7 +274,7 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
{ {
res = deflate(zp, flush ? Z_FINISH : Z_NO_FLUSH); res = deflate(zp, flush ? Z_FINISH : Z_NO_FLUSH);
if (res == Z_STREAM_ERROR) if (res == Z_STREAM_ERROR)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not compress data: %s\n", zp->msg); "could not compress data: %s\n", zp->msg);
if ((flush && (zp->avail_out < cs->zlibOutSize)) if ((flush && (zp->avail_out < cs->zlibOutSize))
|| (zp->avail_out == 0) || (zp->avail_out == 0)
...@@ -295,7 +295,7 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush) ...@@ -295,7 +295,7 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
size_t len = cs->zlibOutSize - zp->avail_out; size_t len = cs->zlibOutSize - zp->avail_out;
if (cs->writeF(AH, out, len) != len) if (cs->writeF(AH, out, len) != len)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not write to output file: %s\n", "could not write to output file: %s\n",
strerror(errno)); strerror(errno));
} }
...@@ -318,7 +318,7 @@ WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs, ...@@ -318,7 +318,7 @@ WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
/* /*
* we have either succeeded in writing dLen bytes or we have called * we have either succeeded in writing dLen bytes or we have called
* die_horribly() * exit_horribly()
*/ */
return dLen; return dLen;
} }
...@@ -361,7 +361,7 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF) ...@@ -361,7 +361,7 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF)
res = inflate(zp, 0); res = inflate(zp, 0);
if (res != Z_OK && res != Z_STREAM_END) if (res != Z_OK && res != Z_STREAM_END)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not uncompress data: %s\n", zp->msg); "could not uncompress data: %s\n", zp->msg);
out[ZLIB_OUT_SIZE - zp->avail_out] = '\0'; out[ZLIB_OUT_SIZE - zp->avail_out] = '\0';
...@@ -377,7 +377,7 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF) ...@@ -377,7 +377,7 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF)
zp->avail_out = ZLIB_OUT_SIZE; zp->avail_out = ZLIB_OUT_SIZE;
res = inflate(zp, 0); res = inflate(zp, 0);
if (res != Z_OK && res != Z_STREAM_END) if (res != Z_OK && res != Z_STREAM_END)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not uncompress data: %s\n", zp->msg); "could not uncompress data: %s\n", zp->msg);
out[ZLIB_OUT_SIZE - zp->avail_out] = '\0'; out[ZLIB_OUT_SIZE - zp->avail_out] = '\0';
...@@ -385,7 +385,7 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF) ...@@ -385,7 +385,7 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF)
} }
if (inflateEnd(zp) != Z_OK) if (inflateEnd(zp) != Z_OK)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not close compression library: %s\n", zp->msg); "could not close compression library: %s\n", zp->msg);
free(buf); free(buf);
...@@ -426,7 +426,7 @@ WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs, ...@@ -426,7 +426,7 @@ WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
* do a check here as well... * do a check here as well...
*/ */
if (cs->writeF(AH, data, dLen) != dLen) if (cs->writeF(AH, data, dLen) != dLen)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not write to output file: %s\n", "could not write to output file: %s\n",
strerror(errno)); strerror(errno));
return dLen; return dLen;
......
...@@ -49,6 +49,7 @@ static void AddAcl(PQExpBuffer aclbuf, const char *keyword, ...@@ -49,6 +49,7 @@ static void AddAcl(PQExpBuffer aclbuf, const char *keyword,
#ifdef WIN32 #ifdef WIN32
static bool parallel_init_done = false; static bool parallel_init_done = false;
static DWORD tls_index; static DWORD tls_index;
static DWORD mainThreadId;
#endif #endif
void void
...@@ -59,6 +60,7 @@ init_parallel_dump_utils(void) ...@@ -59,6 +60,7 @@ init_parallel_dump_utils(void)
{ {
tls_index = TlsAlloc(); tls_index = TlsAlloc();
parallel_init_done = true; parallel_init_done = true;
mainThreadId = GetCurrentThreadId();
} }
#endif #endif
} }
...@@ -1320,5 +1322,9 @@ exit_nicely(int code) ...@@ -1320,5 +1322,9 @@ exit_nicely(int code)
while (--on_exit_nicely_index >= 0) while (--on_exit_nicely_index >= 0)
(*on_exit_nicely_list[on_exit_nicely_index].function)(code, (*on_exit_nicely_list[on_exit_nicely_index].function)(code,
on_exit_nicely_list[on_exit_nicely_index].arg); on_exit_nicely_list[on_exit_nicely_index].arg);
#ifdef WIN32
if (parallel_init_done && GetCurrentThreadId() != mainThreadId)
ExitThread(code);
#endif
exit(code); exit(code);
} }
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
CATALOG_NAME = pg_dump CATALOG_NAME = pg_dump
AVAIL_LANGUAGES = de es fr it ja ko pt_BR sv tr zh_CN zh_TW AVAIL_LANGUAGES = de es fr it ja ko pt_BR sv tr zh_CN zh_TW
GETTEXT_FILES = pg_dump.c common.c pg_backup_archiver.c pg_backup_custom.c \ GETTEXT_FILES = pg_dump.c common.c pg_backup_archiver.c pg_backup_custom.c \
pg_backup_db.c pg_backup_files.c pg_backup_null.c \ pg_backup_db.c pg_backup_null.c \
pg_backup_tar.c pg_restore.c pg_dumpall.c \ pg_backup_tar.c pg_restore.c pg_dumpall.c \
../../port/exec.c ../../port/exec.c
GETTEXT_TRIGGERS = write_msg:2 die_horribly:3 exit_horribly:2 simple_prompt \ GETTEXT_TRIGGERS = write_msg:2 exit_horribly:2 simple_prompt \
ExecuteSqlCommand:3 ahlog:3 ExecuteSqlCommand:3 ahlog:3 warn_or_exit_horribly:3
GETTEXT_FLAGS = \ GETTEXT_FLAGS = \
write_msg:2:c-format \ write_msg:2:c-format \
die_horribly:3:c-format \
exit_horribly:2:c-format \ exit_horribly:2:c-format \
ahlog:3:c-format ahlog:3:c-format \
warn_or_exit_horribly:3:c-format
This diff is collapsed.
...@@ -323,10 +323,9 @@ typedef struct _tocEntry ...@@ -323,10 +323,9 @@ typedef struct _tocEntry
int nLockDeps; /* number of such dependencies */ int nLockDeps; /* number of such dependencies */
} TocEntry; } TocEntry;
extern void on_exit_close_archive(Archive *AHX);
extern void die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4), noreturn)); extern void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
extern void die_on_query_failure(ArchiveHandle *AH, const char *modulename, const char *query) __attribute__((noreturn));
extern void warn_or_die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
extern void WriteTOC(ArchiveHandle *AH); extern void WriteTOC(ArchiveHandle *AH);
extern void ReadTOC(ArchiveHandle *AH); extern void ReadTOC(ArchiveHandle *AH);
......
...@@ -146,14 +146,14 @@ InitArchiveFmt_Custom(ArchiveHandle *AH) ...@@ -146,14 +146,14 @@ InitArchiveFmt_Custom(ArchiveHandle *AH)
{ {
AH->FH = fopen(AH->fSpec, PG_BINARY_W); AH->FH = fopen(AH->fSpec, PG_BINARY_W);
if (!AH->FH) if (!AH->FH)
die_horribly(AH, modulename, "could not open output file \"%s\": %s\n", exit_horribly(modulename, "could not open output file \"%s\": %s\n",
AH->fSpec, strerror(errno)); AH->fSpec, strerror(errno));
} }
else else
{ {
AH->FH = stdout; AH->FH = stdout;
if (!AH->FH) if (!AH->FH)
die_horribly(AH, modulename, "could not open output file: %s\n", exit_horribly(modulename, "could not open output file: %s\n",
strerror(errno)); strerror(errno));
} }
...@@ -165,14 +165,14 @@ InitArchiveFmt_Custom(ArchiveHandle *AH) ...@@ -165,14 +165,14 @@ InitArchiveFmt_Custom(ArchiveHandle *AH)
{ {
AH->FH = fopen(AH->fSpec, PG_BINARY_R); AH->FH = fopen(AH->fSpec, PG_BINARY_R);
if (!AH->FH) if (!AH->FH)
die_horribly(AH, modulename, "could not open input file \"%s\": %s\n", exit_horribly(modulename, "could not open input file \"%s\": %s\n",
AH->fSpec, strerror(errno)); AH->fSpec, strerror(errno));
} }
else else
{ {
AH->FH = stdin; AH->FH = stdin;
if (!AH->FH) if (!AH->FH)
die_horribly(AH, modulename, "could not open input file: %s\n", exit_horribly(modulename, "could not open input file: %s\n",
strerror(errno)); strerror(errno));
} }
...@@ -367,7 +367,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) ...@@ -367,7 +367,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
lclContext *ctx = (lclContext *) AH->formatData; lclContext *ctx = (lclContext *) AH->formatData;
if (oid == 0) if (oid == 0)
die_horribly(AH, modulename, "invalid OID for large object\n"); exit_horribly(modulename, "invalid OID for large object\n");
WriteInt(AH, oid); WriteInt(AH, oid);
...@@ -437,7 +437,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) ...@@ -437,7 +437,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
break; break;
default: /* Always have a default */ default: /* Always have a default */
die_horribly(AH, modulename, exit_horribly(modulename,
"unrecognized data block type (%d) while searching archive\n", "unrecognized data block type (%d) while searching archive\n",
blkType); blkType);
break; break;
...@@ -449,7 +449,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) ...@@ -449,7 +449,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
{ {
/* We can just seek to the place we need to be. */ /* We can just seek to the place we need to be. */
if (fseeko(AH->FH, tctx->dataPos, SEEK_SET) != 0) if (fseeko(AH->FH, tctx->dataPos, SEEK_SET) != 0)
die_horribly(AH, modulename, "error during file seek: %s\n", exit_horribly(modulename, "error during file seek: %s\n",
strerror(errno)); strerror(errno));
_readBlockHeader(AH, &blkType, &id); _readBlockHeader(AH, &blkType, &id);
...@@ -459,24 +459,24 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) ...@@ -459,24 +459,24 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
if (blkType == EOF) if (blkType == EOF)
{ {
if (tctx->dataState == K_OFFSET_POS_NOT_SET) if (tctx->dataState == K_OFFSET_POS_NOT_SET)
die_horribly(AH, modulename, "could not find block ID %d in archive -- " exit_horribly(modulename, "could not find block ID %d in archive -- "
"possibly due to out-of-order restore request, " "possibly due to out-of-order restore request, "
"which cannot be handled due to lack of data offsets in archive\n", "which cannot be handled due to lack of data offsets in archive\n",
te->dumpId); te->dumpId);
else if (!ctx->hasSeek) else if (!ctx->hasSeek)
die_horribly(AH, modulename, "could not find block ID %d in archive -- " exit_horribly(modulename, "could not find block ID %d in archive -- "
"possibly due to out-of-order restore request, " "possibly due to out-of-order restore request, "
"which cannot be handled due to non-seekable input file\n", "which cannot be handled due to non-seekable input file\n",
te->dumpId); te->dumpId);
else /* huh, the dataPos led us to EOF? */ else /* huh, the dataPos led us to EOF? */
die_horribly(AH, modulename, "could not find block ID %d in archive -- " exit_horribly(modulename, "could not find block ID %d in archive -- "
"possibly corrupt archive\n", "possibly corrupt archive\n",
te->dumpId); te->dumpId);
} }
/* Are we sane? */ /* Are we sane? */
if (id != te->dumpId) if (id != te->dumpId)
die_horribly(AH, modulename, "found unexpected block ID (%d) when reading data -- expected %d\n", exit_horribly(modulename, "found unexpected block ID (%d) when reading data -- expected %d\n",
id, te->dumpId); id, te->dumpId);
switch (blkType) switch (blkType)
...@@ -490,7 +490,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) ...@@ -490,7 +490,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
break; break;
default: /* Always have a default */ default: /* Always have a default */
die_horribly(AH, modulename, "unrecognized data block type %d while restoring archive\n", exit_horribly(modulename, "unrecognized data block type %d while restoring archive\n",
blkType); blkType);
break; break;
} }
...@@ -571,10 +571,10 @@ _skipData(ArchiveHandle *AH) ...@@ -571,10 +571,10 @@ _skipData(ArchiveHandle *AH)
if (cnt != blkLen) if (cnt != blkLen)
{ {
if (feof(AH->FH)) if (feof(AH->FH))
die_horribly(AH, modulename, exit_horribly(modulename,
"could not read from input file: end of file\n"); "could not read from input file: end of file\n");
else else
die_horribly(AH, modulename, exit_horribly(modulename,
"could not read from input file: %s\n", strerror(errno)); "could not read from input file: %s\n", strerror(errno));
} }
...@@ -604,7 +604,7 @@ _WriteByte(ArchiveHandle *AH, const int i) ...@@ -604,7 +604,7 @@ _WriteByte(ArchiveHandle *AH, const int i)
if (res != EOF) if (res != EOF)
ctx->filePos += 1; ctx->filePos += 1;
else else
die_horribly(AH, modulename, "could not write byte: %s\n", strerror(errno)); exit_horribly(modulename, "could not write byte: %s\n", strerror(errno));
return res; return res;
} }
...@@ -624,7 +624,7 @@ _ReadByte(ArchiveHandle *AH) ...@@ -624,7 +624,7 @@ _ReadByte(ArchiveHandle *AH)
res = getc(AH->FH); res = getc(AH->FH);
if (res == EOF) if (res == EOF)
die_horribly(AH, modulename, "unexpected end of file\n"); exit_horribly(modulename, "unexpected end of file\n");
ctx->filePos += 1; ctx->filePos += 1;
return res; return res;
} }
...@@ -645,7 +645,7 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len) ...@@ -645,7 +645,7 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
res = fwrite(buf, 1, len, AH->FH); res = fwrite(buf, 1, len, AH->FH);
if (res != len) if (res != len)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not write to output file: %s\n", strerror(errno)); "could not write to output file: %s\n", strerror(errno));
ctx->filePos += res; ctx->filePos += res;
...@@ -712,7 +712,7 @@ _CloseArchive(ArchiveHandle *AH) ...@@ -712,7 +712,7 @@ _CloseArchive(ArchiveHandle *AH)
} }
if (fclose(AH->FH) != 0) if (fclose(AH->FH) != 0)
die_horribly(AH, modulename, "could not close archive file: %s\n", strerror(errno)); exit_horribly(modulename, "could not close archive file: %s\n", strerror(errno));
AH->FH = NULL; AH->FH = NULL;
} }
...@@ -731,36 +731,36 @@ _ReopenArchive(ArchiveHandle *AH) ...@@ -731,36 +731,36 @@ _ReopenArchive(ArchiveHandle *AH)
pgoff_t tpos; pgoff_t tpos;
if (AH->mode == archModeWrite) if (AH->mode == archModeWrite)
die_horribly(AH, modulename, "can only reopen input archives\n"); exit_horribly(modulename, "can only reopen input archives\n");
/* /*
* These two cases are user-facing errors since they represent unsupported * These two cases are user-facing errors since they represent unsupported
* (but not invalid) use-cases. Word the error messages appropriately. * (but not invalid) use-cases. Word the error messages appropriately.
*/ */
if (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0) if (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0)
die_horribly(AH, modulename, "parallel restore from stdin is not supported\n"); exit_horribly(modulename, "parallel restore from stdin is not supported\n");
if (!ctx->hasSeek) if (!ctx->hasSeek)
die_horribly(AH, modulename, "parallel restore from non-seekable file is not supported\n"); exit_horribly(modulename, "parallel restore from non-seekable file is not supported\n");
errno = 0; errno = 0;
tpos = ftello(AH->FH); tpos = ftello(AH->FH);
if (errno) if (errno)
die_horribly(AH, modulename, "could not determine seek position in archive file: %s\n", exit_horribly(modulename, "could not determine seek position in archive file: %s\n",
strerror(errno)); strerror(errno));
#ifndef WIN32 #ifndef WIN32
if (fclose(AH->FH) != 0) if (fclose(AH->FH) != 0)
die_horribly(AH, modulename, "could not close archive file: %s\n", exit_horribly(modulename, "could not close archive file: %s\n",
strerror(errno)); strerror(errno));
#endif #endif
AH->FH = fopen(AH->fSpec, PG_BINARY_R); AH->FH = fopen(AH->fSpec, PG_BINARY_R);
if (!AH->FH) if (!AH->FH)
die_horribly(AH, modulename, "could not open input file \"%s\": %s\n", exit_horribly(modulename, "could not open input file \"%s\": %s\n",
AH->fSpec, strerror(errno)); AH->fSpec, strerror(errno));
if (fseeko(AH->FH, tpos, SEEK_SET) != 0) if (fseeko(AH->FH, tpos, SEEK_SET) != 0)
die_horribly(AH, modulename, "could not set seek position in archive file: %s\n", exit_horribly(modulename, "could not set seek position in archive file: %s\n",
strerror(errno)); strerror(errno));
} }
...@@ -778,7 +778,7 @@ _Clone(ArchiveHandle *AH) ...@@ -778,7 +778,7 @@ _Clone(ArchiveHandle *AH)
/* sanity check, shouldn't happen */ /* sanity check, shouldn't happen */
if (ctx->cs != NULL) if (ctx->cs != NULL)
die_horribly(AH, modulename, "compressor active\n"); exit_horribly(modulename, "compressor active\n");
/* /*
* Note: we do not make a local lo_buf because we expect at most one BLOBS * Note: we do not make a local lo_buf because we expect at most one BLOBS
...@@ -840,7 +840,7 @@ _readBlockHeader(ArchiveHandle *AH, int *type, int *id) ...@@ -840,7 +840,7 @@ _readBlockHeader(ArchiveHandle *AH, int *type, int *id)
int byt; int byt;
/* /*
* Note: if we are at EOF with a pre-1.3 input file, we'll die_horribly * Note: if we are at EOF with a pre-1.3 input file, we'll exit_horribly
* inside ReadInt rather than returning EOF. It doesn't seem worth * inside ReadInt rather than returning EOF. It doesn't seem worth
* jumping through hoops to deal with that case better, because no such * jumping through hoops to deal with that case better, because no such
* files are likely to exist in the wild: only some 7.1 development * files are likely to exist in the wild: only some 7.1 development
...@@ -905,10 +905,10 @@ _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen) ...@@ -905,10 +905,10 @@ _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
if (cnt != blkLen) if (cnt != blkLen)
{ {
if (feof(AH->FH)) if (feof(AH->FH))
die_horribly(AH, modulename, exit_horribly(modulename,
"could not read from input file: end of file\n"); "could not read from input file: end of file\n");
else else
die_horribly(AH, modulename, exit_horribly(modulename,
"could not read from input file: %s\n", strerror(errno)); "could not read from input file: %s\n", strerror(errno));
} }
return cnt; return cnt;
......
...@@ -30,13 +30,13 @@ static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char * ...@@ -30,13 +30,13 @@ static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char *
static void notice_processor(void *arg, const char *message); static void notice_processor(void *arg, const char *message);
static int static int
_parse_version(ArchiveHandle *AH, const char *versionString) _parse_version(const char *versionString)
{ {
int v; int v;
v = parse_version(versionString); v = parse_version(versionString);
if (v < 0) if (v < 0)
die_horribly(AH, modulename, "could not parse version string \"%s\"\n", versionString); exit_horribly(modulename, "could not parse version string \"%s\"\n", versionString);
return v; return v;
} }
...@@ -48,13 +48,13 @@ _check_database_version(ArchiveHandle *AH) ...@@ -48,13 +48,13 @@ _check_database_version(ArchiveHandle *AH)
const char *remoteversion_str; const char *remoteversion_str;
int remoteversion; int remoteversion;
myversion = _parse_version(AH, PG_VERSION); myversion = _parse_version(PG_VERSION);
remoteversion_str = PQparameterStatus(AH->connection, "server_version"); remoteversion_str = PQparameterStatus(AH->connection, "server_version");
if (!remoteversion_str) if (!remoteversion_str)
die_horribly(AH, modulename, "could not get server_version from libpq\n"); exit_horribly(modulename, "could not get server_version from libpq\n");
remoteversion = _parse_version(AH, remoteversion_str); remoteversion = _parse_version(remoteversion_str);
AH->public.remoteVersionStr = pg_strdup(remoteversion_str); AH->public.remoteVersionStr = pg_strdup(remoteversion_str);
AH->public.remoteVersion = remoteversion; AH->public.remoteVersion = remoteversion;
...@@ -67,7 +67,7 @@ _check_database_version(ArchiveHandle *AH) ...@@ -67,7 +67,7 @@ _check_database_version(ArchiveHandle *AH)
{ {
write_msg(NULL, "server version: %s; %s version: %s\n", write_msg(NULL, "server version: %s; %s version: %s\n",
remoteversion_str, progname, PG_VERSION); remoteversion_str, progname, PG_VERSION);
die_horribly(AH, NULL, "aborting because of server version mismatch\n"); exit_horribly(NULL, "aborting because of server version mismatch\n");
} }
} }
...@@ -145,7 +145,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) ...@@ -145,7 +145,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
{ {
password = simple_prompt("Password: ", 100, false); password = simple_prompt("Password: ", 100, false);
if (password == NULL) if (password == NULL)
die_horribly(AH, modulename, "out of memory\n"); exit_horribly(modulename, "out of memory\n");
} }
do do
...@@ -176,12 +176,12 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) ...@@ -176,12 +176,12 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
free(values); free(values);
if (!newConn) if (!newConn)
die_horribly(AH, modulename, "failed to reconnect to database\n"); exit_horribly(modulename, "failed to reconnect to database\n");
if (PQstatus(newConn) == CONNECTION_BAD) if (PQstatus(newConn) == CONNECTION_BAD)
{ {
if (!PQconnectionNeedsPassword(newConn)) if (!PQconnectionNeedsPassword(newConn))
die_horribly(AH, modulename, "could not reconnect to database: %s", exit_horribly(modulename, "could not reconnect to database: %s",
PQerrorMessage(newConn)); PQerrorMessage(newConn));
PQfinish(newConn); PQfinish(newConn);
...@@ -197,10 +197,10 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) ...@@ -197,10 +197,10 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
if (AH->promptPassword != TRI_NO) if (AH->promptPassword != TRI_NO)
password = simple_prompt("Password: ", 100, false); password = simple_prompt("Password: ", 100, false);
else else
die_horribly(AH, modulename, "connection needs password\n"); exit_horribly(modulename, "connection needs password\n");
if (password == NULL) if (password == NULL)
die_horribly(AH, modulename, "out of memory\n"); exit_horribly(modulename, "out of memory\n");
new_pass = true; new_pass = true;
} }
} while (new_pass); } while (new_pass);
...@@ -238,13 +238,13 @@ ConnectDatabase(Archive *AHX, ...@@ -238,13 +238,13 @@ ConnectDatabase(Archive *AHX,
bool new_pass; bool new_pass;
if (AH->connection) if (AH->connection)
die_horribly(AH, modulename, "already connected to a database\n"); exit_horribly(modulename, "already connected to a database\n");
if (prompt_password == TRI_YES && password == NULL) if (prompt_password == TRI_YES && password == NULL)
{ {
password = simple_prompt("Password: ", 100, false); password = simple_prompt("Password: ", 100, false);
if (password == NULL) if (password == NULL)
die_horribly(AH, modulename, "out of memory\n"); exit_horribly(modulename, "out of memory\n");
} }
AH->promptPassword = prompt_password; AH->promptPassword = prompt_password;
...@@ -280,7 +280,7 @@ ConnectDatabase(Archive *AHX, ...@@ -280,7 +280,7 @@ ConnectDatabase(Archive *AHX,
free(values); free(values);
if (!AH->connection) if (!AH->connection)
die_horribly(AH, modulename, "failed to connect to database\n"); exit_horribly(modulename, "failed to connect to database\n");
if (PQstatus(AH->connection) == CONNECTION_BAD && if (PQstatus(AH->connection) == CONNECTION_BAD &&
PQconnectionNeedsPassword(AH->connection) && PQconnectionNeedsPassword(AH->connection) &&
...@@ -290,7 +290,7 @@ ConnectDatabase(Archive *AHX, ...@@ -290,7 +290,7 @@ ConnectDatabase(Archive *AHX,
PQfinish(AH->connection); PQfinish(AH->connection);
password = simple_prompt("Password: ", 100, false); password = simple_prompt("Password: ", 100, false);
if (password == NULL) if (password == NULL)
die_horribly(AH, modulename, "out of memory\n"); exit_horribly(modulename, "out of memory\n");
new_pass = true; new_pass = true;
} }
} while (new_pass); } while (new_pass);
...@@ -299,7 +299,7 @@ ConnectDatabase(Archive *AHX, ...@@ -299,7 +299,7 @@ ConnectDatabase(Archive *AHX,
/* check to see that the backend connection was successfully made */ /* check to see that the backend connection was successfully made */
if (PQstatus(AH->connection) == CONNECTION_BAD) if (PQstatus(AH->connection) == CONNECTION_BAD)
die_horribly(AH, modulename, "connection to database \"%s\" failed: %s", exit_horribly(modulename, "connection to database \"%s\" failed: %s",
PQdb(AH->connection), PQerrorMessage(AH->connection)); PQdb(AH->connection), PQerrorMessage(AH->connection));
/* check for version mismatch */ /* check for version mismatch */
...@@ -331,6 +331,14 @@ notice_processor(void *arg, const char *message) ...@@ -331,6 +331,14 @@ notice_processor(void *arg, const char *message)
write_msg(NULL, "%s", message); write_msg(NULL, "%s", message);
} }
/* Like exit_horribly(), but with a complaint about a particular query. */
static void
die_on_query_failure(ArchiveHandle *AH, const char *modulename, const char *query)
{
write_msg(modulename, "query failed: %s",
PQerrorMessage(AH->connection));
exit_horribly(modulename, "query was: %s\n", query);
}
void void
ExecuteSqlStatement(Archive *AHX, const char *query) ExecuteSqlStatement(Archive *AHX, const char *query)
...@@ -393,7 +401,7 @@ ExecuteSqlCommand(ArchiveHandle *AH, const char *qry, const char *desc) ...@@ -393,7 +401,7 @@ ExecuteSqlCommand(ArchiveHandle *AH, const char *qry, const char *desc)
errStmt[DB_MAX_ERR_STMT - 2] = '.'; errStmt[DB_MAX_ERR_STMT - 2] = '.';
errStmt[DB_MAX_ERR_STMT - 1] = '\0'; errStmt[DB_MAX_ERR_STMT - 1] = '\0';
} }
warn_or_die_horribly(AH, modulename, "%s: %s Command was: %s\n", warn_or_exit_horribly(AH, modulename, "%s: %s Command was: %s\n",
desc, PQerrorMessage(conn), errStmt); desc, PQerrorMessage(conn), errStmt);
break; break;
} }
...@@ -495,7 +503,7 @@ ExecuteSqlCommandBuf(ArchiveHandle *AH, const char *buf, size_t bufLen) ...@@ -495,7 +503,7 @@ ExecuteSqlCommandBuf(ArchiveHandle *AH, const char *buf, size_t bufLen)
*/ */
if (AH->pgCopyIn && if (AH->pgCopyIn &&
PQputCopyData(AH->connection, buf, bufLen) <= 0) PQputCopyData(AH->connection, buf, bufLen) <= 0)
die_horribly(AH, modulename, "error returned by PQputCopyData: %s", exit_horribly(modulename, "error returned by PQputCopyData: %s",
PQerrorMessage(AH->connection)); PQerrorMessage(AH->connection));
} }
else if (AH->outputKind == OUTPUT_OTHERDATA) else if (AH->outputKind == OUTPUT_OTHERDATA)
...@@ -541,13 +549,13 @@ EndDBCopyMode(ArchiveHandle *AH, TocEntry *te) ...@@ -541,13 +549,13 @@ EndDBCopyMode(ArchiveHandle *AH, TocEntry *te)
PGresult *res; PGresult *res;
if (PQputCopyEnd(AH->connection, NULL) <= 0) if (PQputCopyEnd(AH->connection, NULL) <= 0)
die_horribly(AH, modulename, "error returned by PQputCopyEnd: %s", exit_horribly(modulename, "error returned by PQputCopyEnd: %s",
PQerrorMessage(AH->connection)); PQerrorMessage(AH->connection));
/* Check command status and return to normal libpq state */ /* Check command status and return to normal libpq state */
res = PQgetResult(AH->connection); res = PQgetResult(AH->connection);
if (PQresultStatus(res) != PGRES_COMMAND_OK) if (PQresultStatus(res) != PGRES_COMMAND_OK)
warn_or_die_horribly(AH, modulename, "COPY failed for table \"%s\": %s", warn_or_exit_horribly(AH, modulename, "COPY failed for table \"%s\": %s",
te->tag, PQerrorMessage(AH->connection)); te->tag, PQerrorMessage(AH->connection));
PQclear(res); PQclear(res);
......
...@@ -142,7 +142,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) ...@@ -142,7 +142,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
*/ */
if (!AH->fSpec || strcmp(AH->fSpec, "") == 0) if (!AH->fSpec || strcmp(AH->fSpec, "") == 0)
die_horribly(AH, modulename, "no output directory specified\n"); exit_horribly(modulename, "no output directory specified\n");
ctx->directory = AH->fSpec; ctx->directory = AH->fSpec;
...@@ -160,7 +160,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) ...@@ -160,7 +160,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
tocFH = cfopen_read(fname, PG_BINARY_R); tocFH = cfopen_read(fname, PG_BINARY_R);
if (tocFH == NULL) if (tocFH == NULL)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not open input file \"%s\": %s\n", "could not open input file \"%s\": %s\n",
fname, strerror(errno)); fname, strerror(errno));
...@@ -177,7 +177,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) ...@@ -177,7 +177,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
/* Nothing else in the file, so close it again... */ /* Nothing else in the file, so close it again... */
if (cfclose(tocFH) != 0) if (cfclose(tocFH) != 0)
die_horribly(AH, modulename, "could not close TOC file: %s\n", exit_horribly(modulename, "could not close TOC file: %s\n",
strerror(errno)); strerror(errno));
ctx->dataFH = NULL; ctx->dataFH = NULL;
} }
...@@ -288,7 +288,7 @@ _StartData(ArchiveHandle *AH, TocEntry *te) ...@@ -288,7 +288,7 @@ _StartData(ArchiveHandle *AH, TocEntry *te)
ctx->dataFH = cfopen_write(fname, PG_BINARY_W, AH->compression); ctx->dataFH = cfopen_write(fname, PG_BINARY_W, AH->compression);
if (ctx->dataFH == NULL) if (ctx->dataFH == NULL)
die_horribly(AH, modulename, "could not open output file \"%s\": %s\n", exit_horribly(modulename, "could not open output file \"%s\": %s\n",
fname, strerror(errno)); fname, strerror(errno));
} }
...@@ -346,7 +346,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt) ...@@ -346,7 +346,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt)
cfp = cfopen_read(filename, PG_BINARY_R); cfp = cfopen_read(filename, PG_BINARY_R);
if (!cfp) if (!cfp)
die_horribly(AH, modulename, "could not open input file \"%s\": %s\n", exit_horribly(modulename, "could not open input file \"%s\": %s\n",
filename, strerror(errno)); filename, strerror(errno));
buf = pg_malloc(ZLIB_OUT_SIZE); buf = pg_malloc(ZLIB_OUT_SIZE);
...@@ -357,7 +357,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt) ...@@ -357,7 +357,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt)
free(buf); free(buf);
if (cfclose(cfp) != 0) if (cfclose(cfp) != 0)
die_horribly(AH, modulename, "could not close data file: %s\n", exit_horribly(modulename, "could not close data file: %s\n",
strerror(errno)); strerror(errno));
} }
...@@ -397,7 +397,7 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt) ...@@ -397,7 +397,7 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt)
ctx->blobsTocFH = cfopen_read(fname, PG_BINARY_R); ctx->blobsTocFH = cfopen_read(fname, PG_BINARY_R);
if (ctx->blobsTocFH == NULL) if (ctx->blobsTocFH == NULL)
die_horribly(AH, modulename, "could not open large object TOC file \"%s\" for input: %s\n", exit_horribly(modulename, "could not open large object TOC file \"%s\" for input: %s\n",
fname, strerror(errno)); fname, strerror(errno));
/* Read the blobs TOC file line-by-line, and process each blob */ /* Read the blobs TOC file line-by-line, and process each blob */
...@@ -407,7 +407,7 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt) ...@@ -407,7 +407,7 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt)
char path[MAXPGPATH]; char path[MAXPGPATH];
if (sscanf(line, "%u %s\n", &oid, fname) != 2) if (sscanf(line, "%u %s\n", &oid, fname) != 2)
die_horribly(AH, modulename, "invalid line in large object TOC file: %s\n", exit_horribly(modulename, "invalid line in large object TOC file: %s\n",
line); line);
StartRestoreBlob(AH, oid, ropt->dropSchema); StartRestoreBlob(AH, oid, ropt->dropSchema);
...@@ -416,11 +416,11 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt) ...@@ -416,11 +416,11 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt)
EndRestoreBlob(AH, oid); EndRestoreBlob(AH, oid);
} }
if (!cfeof(ctx->blobsTocFH)) if (!cfeof(ctx->blobsTocFH))
die_horribly(AH, modulename, "error reading large object TOC file \"%s\"\n", exit_horribly(modulename, "error reading large object TOC file \"%s\"\n",
fname); fname);
if (cfclose(ctx->blobsTocFH) != 0) if (cfclose(ctx->blobsTocFH) != 0)
die_horribly(AH, modulename, "could not close large object TOC file \"%s\": %s\n", exit_horribly(modulename, "could not close large object TOC file \"%s\": %s\n",
fname, strerror(errno)); fname, strerror(errno));
ctx->blobsTocFH = NULL; ctx->blobsTocFH = NULL;
...@@ -441,7 +441,7 @@ _WriteByte(ArchiveHandle *AH, const int i) ...@@ -441,7 +441,7 @@ _WriteByte(ArchiveHandle *AH, const int i)
lclContext *ctx = (lclContext *) AH->formatData; lclContext *ctx = (lclContext *) AH->formatData;
if (cfwrite(&c, 1, ctx->dataFH) != 1) if (cfwrite(&c, 1, ctx->dataFH) != 1)
die_horribly(AH, modulename, "could not write byte\n"); exit_horribly(modulename, "could not write byte\n");
return 1; return 1;
} }
...@@ -460,7 +460,7 @@ _ReadByte(ArchiveHandle *AH) ...@@ -460,7 +460,7 @@ _ReadByte(ArchiveHandle *AH)
res = cfgetc(ctx->dataFH); res = cfgetc(ctx->dataFH);
if (res == EOF) if (res == EOF)
die_horribly(AH, modulename, "unexpected end of file\n"); exit_horribly(modulename, "unexpected end of file\n");
return res; return res;
} }
...@@ -477,7 +477,7 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len) ...@@ -477,7 +477,7 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
res = cfwrite(buf, len, ctx->dataFH); res = cfwrite(buf, len, ctx->dataFH);
if (res != len) if (res != len)
die_horribly(AH, modulename, "could not write to output file: %s\n", exit_horribly(modulename, "could not write to output file: %s\n",
strerror(errno)); strerror(errno));
return res; return res;
...@@ -524,7 +524,7 @@ _CloseArchive(ArchiveHandle *AH) ...@@ -524,7 +524,7 @@ _CloseArchive(ArchiveHandle *AH)
/* The TOC is always created uncompressed */ /* The TOC is always created uncompressed */
tocFH = cfopen_write(fname, PG_BINARY_W, 0); tocFH = cfopen_write(fname, PG_BINARY_W, 0);
if (tocFH == NULL) if (tocFH == NULL)
die_horribly(AH, modulename, "could not open output file \"%s\": %s\n", exit_horribly(modulename, "could not open output file \"%s\": %s\n",
fname, strerror(errno)); fname, strerror(errno));
ctx->dataFH = tocFH; ctx->dataFH = tocFH;
...@@ -538,7 +538,7 @@ _CloseArchive(ArchiveHandle *AH) ...@@ -538,7 +538,7 @@ _CloseArchive(ArchiveHandle *AH)
AH->format = archDirectory; AH->format = archDirectory;
WriteToc(AH); WriteToc(AH);
if (cfclose(tocFH) != 0) if (cfclose(tocFH) != 0)
die_horribly(AH, modulename, "could not close TOC file: %s\n", exit_horribly(modulename, "could not close TOC file: %s\n",
strerror(errno)); strerror(errno));
WriteDataChunks(AH); WriteDataChunks(AH);
} }
...@@ -568,7 +568,7 @@ _StartBlobs(ArchiveHandle *AH, TocEntry *te) ...@@ -568,7 +568,7 @@ _StartBlobs(ArchiveHandle *AH, TocEntry *te)
/* The blob TOC file is never compressed */ /* The blob TOC file is never compressed */
ctx->blobsTocFH = cfopen_write(fname, "ab", 0); ctx->blobsTocFH = cfopen_write(fname, "ab", 0);
if (ctx->blobsTocFH == NULL) if (ctx->blobsTocFH == NULL)
die_horribly(AH, modulename, "could not open output file \"%s\": %s\n", exit_horribly(modulename, "could not open output file \"%s\": %s\n",
fname, strerror(errno)); fname, strerror(errno));
} }
...@@ -588,7 +588,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) ...@@ -588,7 +588,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
ctx->dataFH = cfopen_write(fname, PG_BINARY_W, AH->compression); ctx->dataFH = cfopen_write(fname, PG_BINARY_W, AH->compression);
if (ctx->dataFH == NULL) if (ctx->dataFH == NULL)
die_horribly(AH, modulename, "could not open output file \"%s\": %s\n", exit_horribly(modulename, "could not open output file \"%s\": %s\n",
fname, strerror(errno)); fname, strerror(errno));
} }
...@@ -611,7 +611,7 @@ _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) ...@@ -611,7 +611,7 @@ _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
/* register the blob in blobs.toc */ /* register the blob in blobs.toc */
len = snprintf(buf, sizeof(buf), "%u blob_%u.dat\n", oid, oid); len = snprintf(buf, sizeof(buf), "%u blob_%u.dat\n", oid, oid);
if (cfwrite(buf, len, ctx->blobsTocFH) != len) if (cfwrite(buf, len, ctx->blobsTocFH) != len)
die_horribly(AH, modulename, "could not write to blobs TOC file\n"); exit_horribly(modulename, "could not write to blobs TOC file\n");
} }
/* /*
...@@ -667,7 +667,7 @@ prependDirectory(ArchiveHandle *AH, const char *relativeFilename) ...@@ -667,7 +667,7 @@ prependDirectory(ArchiveHandle *AH, const char *relativeFilename)
dname = ctx->directory; dname = ctx->directory;
if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH) if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH)
die_horribly(AH, modulename, "path name too long: %s", dname); exit_horribly(modulename, "path name too long: %s", dname);
strcpy(buf, dname); strcpy(buf, dname);
strcat(buf, "/"); strcat(buf, "/");
......
...@@ -74,7 +74,7 @@ InitArchiveFmt_Null(ArchiveHandle *AH) ...@@ -74,7 +74,7 @@ InitArchiveFmt_Null(ArchiveHandle *AH)
* Now prevent reading... * Now prevent reading...
*/ */
if (AH->mode == archModeRead) if (AH->mode == archModeRead)
die_horribly(AH, NULL, "this format cannot be read\n"); exit_horribly(NULL, "this format cannot be read\n");
} }
/* /*
...@@ -149,7 +149,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) ...@@ -149,7 +149,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
bool old_blob_style = (AH->version < K_VERS_1_12); bool old_blob_style = (AH->version < K_VERS_1_12);
if (oid == 0) if (oid == 0)
die_horribly(AH, NULL, "invalid OID for large object\n"); exit_horribly(NULL, "invalid OID for large object\n");
/* With an old archive we must do drop and create logic here */ /* With an old archive we must do drop and create logic here */
if (old_blob_style && AH->ropt->dropSchema) if (old_blob_style && AH->ropt->dropSchema)
......
...@@ -355,7 +355,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode) ...@@ -355,7 +355,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
* Couldn't find the requested file. Future: do SEEK(0) and * Couldn't find the requested file. Future: do SEEK(0) and
* retry. * retry.
*/ */
die_horribly(AH, modulename, "could not find file \"%s\" in archive\n", filename); exit_horribly(modulename, "could not find file \"%s\" in archive\n", filename);
} }
else else
{ {
...@@ -369,7 +369,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode) ...@@ -369,7 +369,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
if (AH->compression == 0) if (AH->compression == 0)
tm->nFH = ctx->tarFH; tm->nFH = ctx->tarFH;
else else
die_horribly(AH, modulename, "compression is not supported by tar archive format\n"); exit_horribly(modulename, "compression is not supported by tar archive format\n");
/* tm->zFH = gzdopen(dup(fileno(ctx->tarFH)), "rb"); */ /* tm->zFH = gzdopen(dup(fileno(ctx->tarFH)), "rb"); */
#else #else
tm->nFH = ctx->tarFH; tm->nFH = ctx->tarFH;
...@@ -411,7 +411,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode) ...@@ -411,7 +411,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
#endif #endif
if (tm->tmpFH == NULL) if (tm->tmpFH == NULL)
die_horribly(AH, modulename, "could not generate temporary file name: %s\n", strerror(errno)); exit_horribly(modulename, "could not generate temporary file name: %s\n", strerror(errno));
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
...@@ -420,7 +420,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode) ...@@ -420,7 +420,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
sprintf(fmode, "wb%d", AH->compression); sprintf(fmode, "wb%d", AH->compression);
tm->zFH = gzdopen(dup(fileno(tm->tmpFH)), fmode); tm->zFH = gzdopen(dup(fileno(tm->tmpFH)), fmode);
if (tm->zFH == NULL) if (tm->zFH == NULL)
die_horribly(AH, modulename, "could not open temporary file\n"); exit_horribly(modulename, "could not open temporary file\n");
} }
else else
tm->nFH = tm->tmpFH; tm->nFH = tm->tmpFH;
...@@ -447,7 +447,7 @@ tarClose(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -447,7 +447,7 @@ tarClose(ArchiveHandle *AH, TAR_MEMBER *th)
*/ */
if (AH->compression != 0) if (AH->compression != 0)
if (GZCLOSE(th->zFH) != 0) if (GZCLOSE(th->zFH) != 0)
die_horribly(AH, modulename, "could not close tar member\n"); exit_horribly(modulename, "could not close tar member\n");
if (th->mode == 'w') if (th->mode == 'w')
_tarAddFile(AH, th); /* This will close the temp file */ _tarAddFile(AH, th); /* This will close the temp file */
...@@ -547,7 +547,7 @@ _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh) ...@@ -547,7 +547,7 @@ _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh)
res = fread(&((char *) buf)[used], 1, len, th->nFH); res = fread(&((char *) buf)[used], 1, len, th->nFH);
} }
else else
die_horribly(AH, modulename, "internal error -- neither th nor fh specified in tarReadRaw()\n"); exit_horribly(modulename, "internal error -- neither th nor fh specified in tarReadRaw()\n");
} }
ctx->tarFHpos += res + used; ctx->tarFHpos += res + used;
...@@ -584,7 +584,7 @@ tarWrite(const void *buf, size_t len, TAR_MEMBER *th) ...@@ -584,7 +584,7 @@ tarWrite(const void *buf, size_t len, TAR_MEMBER *th)
res = fwrite(buf, 1, len, th->nFH); res = fwrite(buf, 1, len, th->nFH);
if (res != len) if (res != len)
die_horribly(th->AH, modulename, exit_horribly(modulename,
"could not write to output file: %s\n", strerror(errno)); "could not write to output file: %s\n", strerror(errno));
th->pos += res; th->pos += res;
...@@ -672,7 +672,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) ...@@ -672,7 +672,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
* we search the string for it in a paranoid sort of way. * we search the string for it in a paranoid sort of way.
*/ */
if (strncmp(tmpCopy, "copy ", 5) != 0) if (strncmp(tmpCopy, "copy ", 5) != 0)
die_horribly(AH, modulename, exit_horribly(modulename,
"invalid COPY statement -- could not find \"copy\" in string \"%s\"\n", tmpCopy); "invalid COPY statement -- could not find \"copy\" in string \"%s\"\n", tmpCopy);
pos1 = 5; pos1 = 5;
...@@ -690,7 +690,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) ...@@ -690,7 +690,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
break; break;
if (pos2 >= strlen(tmpCopy)) if (pos2 >= strlen(tmpCopy))
die_horribly(AH, modulename, exit_horribly(modulename,
"invalid COPY statement -- could not find \"from stdin\" in string \"%s\" starting at position %lu\n", "invalid COPY statement -- could not find \"from stdin\" in string \"%s\" starting at position %lu\n",
tmpCopy, (unsigned long) pos1); tmpCopy, (unsigned long) pos1);
...@@ -784,7 +784,7 @@ _ReadByte(ArchiveHandle *AH) ...@@ -784,7 +784,7 @@ _ReadByte(ArchiveHandle *AH)
res = tarRead(&c, 1, ctx->FH); res = tarRead(&c, 1, ctx->FH);
if (res != 1) if (res != 1)
die_horribly(AH, modulename, "unexpected end of file\n"); exit_horribly(modulename, "unexpected end of file\n");
ctx->filePos += 1; ctx->filePos += 1;
return c; return c;
} }
...@@ -878,7 +878,7 @@ _CloseArchive(ArchiveHandle *AH) ...@@ -878,7 +878,7 @@ _CloseArchive(ArchiveHandle *AH)
for (i = 0; i < 512; i++) for (i = 0; i < 512; i++)
{ {
if (fputc(0, ctx->tarFH) == EOF) if (fputc(0, ctx->tarFH) == EOF)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not write null block at end of tar archive\n"); "could not write null block at end of tar archive\n");
} }
} }
...@@ -934,7 +934,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) ...@@ -934,7 +934,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
char *sfx; char *sfx;
if (oid == 0) if (oid == 0)
die_horribly(AH, modulename, "invalid OID for large object (%u)\n", oid); exit_horribly(modulename, "invalid OID for large object (%u)\n", oid);
if (AH->compression != 0) if (AH->compression != 0)
sfx = ".gz"; sfx = ".gz";
...@@ -1077,7 +1077,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1077,7 +1077,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
* because pgoff_t can't exceed the compared maximum on their platform. * because pgoff_t can't exceed the compared maximum on their platform.
*/ */
if (th->fileLen > MAX_TAR_MEMBER_FILELEN) if (th->fileLen > MAX_TAR_MEMBER_FILELEN)
die_horribly(AH, modulename, "archive member too large for tar format\n"); exit_horribly(modulename, "archive member too large for tar format\n");
_tarWriteHeader(th); _tarWriteHeader(th);
...@@ -1085,14 +1085,14 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1085,14 +1085,14 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
{ {
res = fwrite(buf, 1, cnt, th->tarFH); res = fwrite(buf, 1, cnt, th->tarFH);
if (res != cnt) if (res != cnt)
die_horribly(AH, modulename, exit_horribly(modulename,
"could not write to output file: %s\n", "could not write to output file: %s\n",
strerror(errno)); strerror(errno));
len += res; len += res;
} }
if (fclose(tmp) != 0) /* This *should* delete it... */ if (fclose(tmp) != 0) /* This *should* delete it... */
die_horribly(AH, modulename, "could not close temporary file: %s\n", exit_horribly(modulename, "could not close temporary file: %s\n",
strerror(errno)); strerror(errno));
if (len != th->fileLen) if (len != th->fileLen)
...@@ -1102,7 +1102,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1102,7 +1102,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) len); snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) len);
snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) th->fileLen); snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) th->fileLen);
die_horribly(AH, modulename, "actual file length (%s) does not match expected (%s)\n", exit_horribly(modulename, "actual file length (%s) does not match expected (%s)\n",
buf1, buf2); buf1, buf2);
} }
...@@ -1110,7 +1110,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1110,7 +1110,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
for (i = 0; i < pad; i++) for (i = 0; i < pad; i++)
{ {
if (fputc('\0', th->tarFH) == EOF) if (fputc('\0', th->tarFH) == EOF)
die_horribly(AH, modulename, "could not output padding at end of tar member\n"); exit_horribly(modulename, "could not output padding at end of tar member\n");
} }
ctx->tarFHpos += len + pad; ctx->tarFHpos += len + pad;
...@@ -1159,7 +1159,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) ...@@ -1159,7 +1159,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
if (!_tarGetHeader(AH, th)) if (!_tarGetHeader(AH, th))
{ {
if (filename) if (filename)
die_horribly(AH, modulename, "could not find header for file \"%s\" in tar archive\n", filename); exit_horribly(modulename, "could not find header for file \"%s\" in tar archive\n", filename);
else else
{ {
/* /*
...@@ -1177,7 +1177,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) ...@@ -1177,7 +1177,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
id = atoi(th->targetFile); id = atoi(th->targetFile);
if ((TocIDRequired(AH, id, AH->ropt) & REQ_DATA) != 0) if ((TocIDRequired(AH, id, AH->ropt) & REQ_DATA) != 0)
die_horribly(AH, modulename, "restoring data out of order is not supported in this archive format: " exit_horribly(modulename, "restoring data out of order is not supported in this archive format: "
"\"%s\" is required, but comes before \"%s\" in the archive file.\n", "\"%s\" is required, but comes before \"%s\" in the archive file.\n",
th->targetFile, filename); th->targetFile, filename);
...@@ -1189,7 +1189,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) ...@@ -1189,7 +1189,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
_tarReadRaw(AH, &header[0], 512, NULL, ctx->tarFH); _tarReadRaw(AH, &header[0], 512, NULL, ctx->tarFH);
if (!_tarGetHeader(AH, th)) if (!_tarGetHeader(AH, th))
die_horribly(AH, modulename, "could not find header for file \"%s\" in tar archive\n", filename); exit_horribly(modulename, "could not find header for file \"%s\" in tar archive\n", filename);
} }
ctx->tarNextMember = ctx->tarFHpos + ((th->fileLen + 511) & ~511); ctx->tarNextMember = ctx->tarFHpos + ((th->fileLen + 511) & ~511);
...@@ -1222,7 +1222,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1222,7 +1222,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) ftello(ctx->tarFH)); snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) ftello(ctx->tarFH));
snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) ftello(ctx->tarFHpos)); snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) ftello(ctx->tarFHpos));
die_horribly(AH, modulename, exit_horribly(modulename,
"mismatch in actual vs. predicted file position (%s vs. %s)\n", "mismatch in actual vs. predicted file position (%s vs. %s)\n",
buf1, buf2); buf1, buf2);
} }
...@@ -1237,7 +1237,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1237,7 +1237,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
return 0; return 0;
if (len != 512) if (len != 512)
die_horribly(AH, modulename, exit_horribly(modulename,
ngettext("incomplete tar header found (%lu byte)\n", ngettext("incomplete tar header found (%lu byte)\n",
"incomplete tar header found (%lu bytes)\n", "incomplete tar header found (%lu bytes)\n",
len), len),
...@@ -1285,7 +1285,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1285,7 +1285,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
char buf[100]; char buf[100];
snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) ftello(ctx->tarFH)); snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) ftello(ctx->tarFH));
die_horribly(AH, modulename, exit_horribly(modulename,
"corrupt tar header found in %s " "corrupt tar header found in %s "
"(expected %d, computed %d) file position %s\n", "(expected %d, computed %d) file position %s\n",
tag, sum, chk, buf); tag, sum, chk, buf);
...@@ -1379,5 +1379,5 @@ _tarWriteHeader(TAR_MEMBER *th) ...@@ -1379,5 +1379,5 @@ _tarWriteHeader(TAR_MEMBER *th)
} }
if (fwrite(h, 1, 512, th->tarFH) != 512) if (fwrite(h, 1, 512, th->tarFH) != 512)
die_horribly(th->AH, modulename, "could not write to output file: %s\n", strerror(errno)); exit_horribly(modulename, "could not write to output file: %s\n", strerror(errno));
} }
...@@ -144,7 +144,6 @@ static int serializable_deferrable = 0; ...@@ -144,7 +144,6 @@ static int serializable_deferrable = 0;
static void help(const char *progname); static void help(const char *progname);
static void pgdump_cleanup_at_exit(int code, void *arg);
static void setup_connection(Archive *AH, const char *dumpencoding, static void setup_connection(Archive *AH, const char *dumpencoding,
char *use_role); char *use_role);
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode); static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
...@@ -575,7 +574,9 @@ main(int argc, char **argv) ...@@ -575,7 +574,9 @@ main(int argc, char **argv)
/* Open the output file */ /* Open the output file */
fout = CreateArchive(filename, archiveFormat, compressLevel, archiveMode); fout = CreateArchive(filename, archiveFormat, compressLevel, archiveMode);
on_exit_nicely(pgdump_cleanup_at_exit, fout);
/* Register the cleanup hook */
on_exit_close_archive(fout);
if (fout == NULL) if (fout == NULL)
exit_horribly(NULL, "could not open output file \"%s\" for writing\n", filename); exit_horribly(NULL, "could not open output file \"%s\" for writing\n", filename);
...@@ -836,14 +837,6 @@ help(const char *progname) ...@@ -836,14 +837,6 @@ help(const char *progname)
printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n")); printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
} }
static void
pgdump_cleanup_at_exit(int code, void *arg)
{
Archive *AH = (Archive *) arg;
DisconnectDatabase(AH);
}
static void static void
setup_connection(Archive *AH, const char *dumpencoding, char *use_role) setup_connection(Archive *AH, const char *dumpencoding, char *use_role)
{ {
......
...@@ -379,6 +379,13 @@ main(int argc, char **argv) ...@@ -379,6 +379,13 @@ main(int argc, char **argv)
AH = OpenArchive(inputFileSpec, opts->format); AH = OpenArchive(inputFileSpec, opts->format);
/*
* We don't have a connection yet but that doesn't matter. The connection
* is initialized to NULL and if we terminate through exit_nicely() while
* it's still NULL, the cleanup function will just be a no-op.
*/
on_exit_close_archive(AH);
/* Let the archiver know how noisy to be */ /* Let the archiver know how noisy to be */
AH->verbose = opts->verbose; AH->verbose = opts->verbose;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment