提交 9d23a70d 编写于 作者: A 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.
上级 b251cf31
......@@ -256,8 +256,8 @@ EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs)
DeflateCompressorZlib(AH, cs, true);
if (deflateEnd(zp) != Z_OK)
die_horribly(AH, modulename,
"could not close compression stream: %s\n", zp->msg);
exit_horribly(modulename,
"could not close compression stream: %s\n", zp->msg);
free(cs->zlibOut);
free(cs->zp);
......@@ -274,8 +274,8 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
{
res = deflate(zp, flush ? Z_FINISH : Z_NO_FLUSH);
if (res == Z_STREAM_ERROR)
die_horribly(AH, modulename,
"could not compress data: %s\n", zp->msg);
exit_horribly(modulename,
"could not compress data: %s\n", zp->msg);
if ((flush && (zp->avail_out < cs->zlibOutSize))
|| (zp->avail_out == 0)
|| (zp->avail_in != 0)
......@@ -295,9 +295,9 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
size_t len = cs->zlibOutSize - zp->avail_out;
if (cs->writeF(AH, out, len) != len)
die_horribly(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));
}
zp->next_out = (void *) out;
zp->avail_out = cs->zlibOutSize;
......@@ -318,7 +318,7 @@ WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
/*
* we have either succeeded in writing dLen bytes or we have called
* die_horribly()
* exit_horribly()
*/
return dLen;
}
......@@ -361,8 +361,8 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF)
res = inflate(zp, 0);
if (res != Z_OK && res != Z_STREAM_END)
die_horribly(AH, modulename,
"could not uncompress data: %s\n", zp->msg);
exit_horribly(modulename,
"could not uncompress data: %s\n", zp->msg);
out[ZLIB_OUT_SIZE - zp->avail_out] = '\0';
ahwrite(out, 1, ZLIB_OUT_SIZE - zp->avail_out, AH);
......@@ -377,16 +377,16 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF)
zp->avail_out = ZLIB_OUT_SIZE;
res = inflate(zp, 0);
if (res != Z_OK && res != Z_STREAM_END)
die_horribly(AH, modulename,
"could not uncompress data: %s\n", zp->msg);
exit_horribly(modulename,
"could not uncompress data: %s\n", zp->msg);
out[ZLIB_OUT_SIZE - zp->avail_out] = '\0';
ahwrite(out, 1, ZLIB_OUT_SIZE - zp->avail_out, AH);
}
if (inflateEnd(zp) != Z_OK)
die_horribly(AH, modulename,
"could not close compression library: %s\n", zp->msg);
exit_horribly(modulename,
"could not close compression library: %s\n", zp->msg);
free(buf);
free(out);
......@@ -426,9 +426,9 @@ WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
* do a check here as well...
*/
if (cs->writeF(AH, data, dLen) != dLen)
die_horribly(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));
return dLen;
}
......
......@@ -49,6 +49,7 @@ static void AddAcl(PQExpBuffer aclbuf, const char *keyword,
#ifdef WIN32
static bool parallel_init_done = false;
static DWORD tls_index;
static DWORD mainThreadId;
#endif
void
......@@ -59,6 +60,7 @@ init_parallel_dump_utils(void)
{
tls_index = TlsAlloc();
parallel_init_done = true;
mainThreadId = GetCurrentThreadId();
}
#endif
}
......@@ -1320,5 +1322,9 @@ exit_nicely(int code)
while (--on_exit_nicely_index >= 0)
(*on_exit_nicely_list[on_exit_nicely_index].function)(code,
on_exit_nicely_list[on_exit_nicely_index].arg);
#ifdef WIN32
if (parallel_init_done && GetCurrentThreadId() != mainThreadId)
ExitThread(code);
#endif
exit(code);
}
......@@ -2,13 +2,13 @@
CATALOG_NAME = pg_dump
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 \
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 \
../../port/exec.c
GETTEXT_TRIGGERS = write_msg:2 die_horribly:3 exit_horribly:2 simple_prompt \
ExecuteSqlCommand:3 ahlog:3
GETTEXT_TRIGGERS = write_msg:2 exit_horribly:2 simple_prompt \
ExecuteSqlCommand:3 ahlog:3 warn_or_exit_horribly:3
GETTEXT_FLAGS = \
write_msg:2:c-format \
die_horribly:3:c-format \
exit_horribly:2:c-format \
ahlog:3:c-format
ahlog:3:c-format \
warn_or_exit_horribly:3:c-format
......@@ -323,10 +323,9 @@ typedef struct _tocEntry
int nLockDeps; /* number of such dependencies */
} 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 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 warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
extern void WriteTOC(ArchiveHandle *AH);
extern void ReadTOC(ArchiveHandle *AH);
......
......@@ -146,15 +146,15 @@ InitArchiveFmt_Custom(ArchiveHandle *AH)
{
AH->FH = fopen(AH->fSpec, PG_BINARY_W);
if (!AH->FH)
die_horribly(AH, modulename, "could not open output file \"%s\": %s\n",
AH->fSpec, strerror(errno));
exit_horribly(modulename, "could not open output file \"%s\": %s\n",
AH->fSpec, strerror(errno));
}
else
{
AH->FH = stdout;
if (!AH->FH)
die_horribly(AH, modulename, "could not open output file: %s\n",
strerror(errno));
exit_horribly(modulename, "could not open output file: %s\n",
strerror(errno));
}
ctx->hasSeek = checkSeek(AH->FH);
......@@ -165,15 +165,15 @@ InitArchiveFmt_Custom(ArchiveHandle *AH)
{
AH->FH = fopen(AH->fSpec, PG_BINARY_R);
if (!AH->FH)
die_horribly(AH, modulename, "could not open input file \"%s\": %s\n",
AH->fSpec, strerror(errno));
exit_horribly(modulename, "could not open input file \"%s\": %s\n",
AH->fSpec, strerror(errno));
}
else
{
AH->FH = stdin;
if (!AH->FH)
die_horribly(AH, modulename, "could not open input file: %s\n",
strerror(errno));
exit_horribly(modulename, "could not open input file: %s\n",
strerror(errno));
}
ctx->hasSeek = checkSeek(AH->FH);
......@@ -367,7 +367,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
lclContext *ctx = (lclContext *) AH->formatData;
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);
......@@ -437,9 +437,9 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
break;
default: /* Always have a default */
die_horribly(AH, modulename,
"unrecognized data block type (%d) while searching archive\n",
blkType);
exit_horribly(modulename,
"unrecognized data block type (%d) while searching archive\n",
blkType);
break;
}
_readBlockHeader(AH, &blkType, &id);
......@@ -449,8 +449,8 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
{
/* We can just seek to the place we need to be. */
if (fseeko(AH->FH, tctx->dataPos, SEEK_SET) != 0)
die_horribly(AH, modulename, "error during file seek: %s\n",
strerror(errno));
exit_horribly(modulename, "error during file seek: %s\n",
strerror(errno));
_readBlockHeader(AH, &blkType, &id);
}
......@@ -459,25 +459,25 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
if (blkType == EOF)
{
if (tctx->dataState == K_OFFSET_POS_NOT_SET)
die_horribly(AH, modulename, "could not find block ID %d in archive -- "
"possibly due to out-of-order restore request, "
"which cannot be handled due to lack of data offsets in archive\n",
te->dumpId);
exit_horribly(modulename, "could not find block ID %d in archive -- "
"possibly due to out-of-order restore request, "
"which cannot be handled due to lack of data offsets in archive\n",
te->dumpId);
else if (!ctx->hasSeek)
die_horribly(AH, modulename, "could not find block ID %d in archive -- "
"possibly due to out-of-order restore request, "
"which cannot be handled due to non-seekable input file\n",
te->dumpId);
exit_horribly(modulename, "could not find block ID %d in archive -- "
"possibly due to out-of-order restore request, "
"which cannot be handled due to non-seekable input file\n",
te->dumpId);
else /* huh, the dataPos led us to EOF? */
die_horribly(AH, modulename, "could not find block ID %d in archive -- "
"possibly corrupt archive\n",
te->dumpId);
exit_horribly(modulename, "could not find block ID %d in archive -- "
"possibly corrupt archive\n",
te->dumpId);
}
/* Are we sane? */
if (id != te->dumpId)
die_horribly(AH, modulename, "found unexpected block ID (%d) when reading data -- expected %d\n",
id, te->dumpId);
exit_horribly(modulename, "found unexpected block ID (%d) when reading data -- expected %d\n",
id, te->dumpId);
switch (blkType)
{
......@@ -490,8 +490,8 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
break;
default: /* Always have a default */
die_horribly(AH, modulename, "unrecognized data block type %d while restoring archive\n",
blkType);
exit_horribly(modulename, "unrecognized data block type %d while restoring archive\n",
blkType);
break;
}
}
......@@ -571,11 +571,11 @@ _skipData(ArchiveHandle *AH)
if (cnt != blkLen)
{
if (feof(AH->FH))
die_horribly(AH, modulename,
"could not read from input file: end of file\n");
exit_horribly(modulename,
"could not read from input file: end of file\n");
else
die_horribly(AH, modulename,
"could not read from input file: %s\n", strerror(errno));
exit_horribly(modulename,
"could not read from input file: %s\n", strerror(errno));
}
ctx->filePos += blkLen;
......@@ -604,7 +604,7 @@ _WriteByte(ArchiveHandle *AH, const int i)
if (res != EOF)
ctx->filePos += 1;
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;
}
......@@ -624,7 +624,7 @@ _ReadByte(ArchiveHandle *AH)
res = getc(AH->FH);
if (res == EOF)
die_horribly(AH, modulename, "unexpected end of file\n");
exit_horribly(modulename, "unexpected end of file\n");
ctx->filePos += 1;
return res;
}
......@@ -645,7 +645,7 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
res = fwrite(buf, 1, len, AH->FH);
if (res != len)
die_horribly(AH, modulename,
exit_horribly(modulename,
"could not write to output file: %s\n", strerror(errno));
ctx->filePos += res;
......@@ -712,7 +712,7 @@ _CloseArchive(ArchiveHandle *AH)
}
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;
}
......@@ -731,37 +731,37 @@ _ReopenArchive(ArchiveHandle *AH)
pgoff_t tpos;
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
* (but not invalid) use-cases. Word the error messages appropriately.
*/
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)
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;
tpos = ftello(AH->FH);
if (errno)
die_horribly(AH, modulename, "could not determine seek position in archive file: %s\n",
strerror(errno));
exit_horribly(modulename, "could not determine seek position in archive file: %s\n",
strerror(errno));
#ifndef WIN32
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));
#endif
AH->FH = fopen(AH->fSpec, PG_BINARY_R);
if (!AH->FH)
die_horribly(AH, modulename, "could not open input file \"%s\": %s\n",
AH->fSpec, strerror(errno));
exit_horribly(modulename, "could not open input file \"%s\": %s\n",
AH->fSpec, strerror(errno));
if (fseeko(AH->FH, tpos, SEEK_SET) != 0)
die_horribly(AH, modulename, "could not set seek position in archive file: %s\n",
strerror(errno));
exit_horribly(modulename, "could not set seek position in archive file: %s\n",
strerror(errno));
}
/*
......@@ -778,7 +778,7 @@ _Clone(ArchiveHandle *AH)
/* sanity check, shouldn't happen */
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
......@@ -840,7 +840,7 @@ _readBlockHeader(ArchiveHandle *AH, int *type, int *id)
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
* 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
......@@ -905,10 +905,10 @@ _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
if (cnt != blkLen)
{
if (feof(AH->FH))
die_horribly(AH, modulename,
"could not read from input file: end of file\n");
exit_horribly(modulename,
"could not read from input file: end of file\n");
else
die_horribly(AH, modulename,
exit_horribly(modulename,
"could not read from input file: %s\n", strerror(errno));
}
return cnt;
......
......@@ -30,13 +30,13 @@ static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char *
static void notice_processor(void *arg, const char *message);
static int
_parse_version(ArchiveHandle *AH, const char *versionString)
_parse_version(const char *versionString)
{
int v;
v = parse_version(versionString);
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;
}
......@@ -48,13 +48,13 @@ _check_database_version(ArchiveHandle *AH)
const char *remoteversion_str;
int remoteversion;
myversion = _parse_version(AH, PG_VERSION);
myversion = _parse_version(PG_VERSION);
remoteversion_str = PQparameterStatus(AH->connection, "server_version");
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.remoteVersion = remoteversion;
......@@ -67,7 +67,7 @@ _check_database_version(ArchiveHandle *AH)
{
write_msg(NULL, "server version: %s; %s version: %s\n",
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)
{
password = simple_prompt("Password: ", 100, false);
if (password == NULL)
die_horribly(AH, modulename, "out of memory\n");
exit_horribly(modulename, "out of memory\n");
}
do
......@@ -176,12 +176,12 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
free(values);
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 (!PQconnectionNeedsPassword(newConn))
die_horribly(AH, modulename, "could not reconnect to database: %s",
exit_horribly(modulename, "could not reconnect to database: %s",
PQerrorMessage(newConn));
PQfinish(newConn);
......@@ -197,10 +197,10 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
if (AH->promptPassword != TRI_NO)
password = simple_prompt("Password: ", 100, false);
else
die_horribly(AH, modulename, "connection needs password\n");
exit_horribly(modulename, "connection needs password\n");
if (password == NULL)
die_horribly(AH, modulename, "out of memory\n");
exit_horribly(modulename, "out of memory\n");
new_pass = true;
}
} while (new_pass);
......@@ -238,13 +238,13 @@ ConnectDatabase(Archive *AHX,
bool new_pass;
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)
{
password = simple_prompt("Password: ", 100, false);
if (password == NULL)
die_horribly(AH, modulename, "out of memory\n");
exit_horribly(modulename, "out of memory\n");
}
AH->promptPassword = prompt_password;
......@@ -280,7 +280,7 @@ ConnectDatabase(Archive *AHX,
free(values);
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 &&
PQconnectionNeedsPassword(AH->connection) &&
......@@ -290,7 +290,7 @@ ConnectDatabase(Archive *AHX,
PQfinish(AH->connection);
password = simple_prompt("Password: ", 100, false);
if (password == NULL)
die_horribly(AH, modulename, "out of memory\n");
exit_horribly(modulename, "out of memory\n");
new_pass = true;
}
} while (new_pass);
......@@ -299,7 +299,7 @@ ConnectDatabase(Archive *AHX,
/* check to see that the backend connection was successfully made */
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));
/* check for version mismatch */
......@@ -331,6 +331,14 @@ notice_processor(void *arg, const char *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
ExecuteSqlStatement(Archive *AHX, const char *query)
......@@ -393,8 +401,8 @@ ExecuteSqlCommand(ArchiveHandle *AH, const char *qry, const char *desc)
errStmt[DB_MAX_ERR_STMT - 2] = '.';
errStmt[DB_MAX_ERR_STMT - 1] = '\0';
}
warn_or_die_horribly(AH, modulename, "%s: %s Command was: %s\n",
desc, PQerrorMessage(conn), errStmt);
warn_or_exit_horribly(AH, modulename, "%s: %s Command was: %s\n",
desc, PQerrorMessage(conn), errStmt);
break;
}
......@@ -495,8 +503,8 @@ ExecuteSqlCommandBuf(ArchiveHandle *AH, const char *buf, size_t bufLen)
*/
if (AH->pgCopyIn &&
PQputCopyData(AH->connection, buf, bufLen) <= 0)
die_horribly(AH, modulename, "error returned by PQputCopyData: %s",
PQerrorMessage(AH->connection));
exit_horribly(modulename, "error returned by PQputCopyData: %s",
PQerrorMessage(AH->connection));
}
else if (AH->outputKind == OUTPUT_OTHERDATA)
{
......@@ -541,14 +549,14 @@ EndDBCopyMode(ArchiveHandle *AH, TocEntry *te)
PGresult *res;
if (PQputCopyEnd(AH->connection, NULL) <= 0)
die_horribly(AH, modulename, "error returned by PQputCopyEnd: %s",
PQerrorMessage(AH->connection));
exit_horribly(modulename, "error returned by PQputCopyEnd: %s",
PQerrorMessage(AH->connection));
/* Check command status and return to normal libpq state */
res = PQgetResult(AH->connection);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
warn_or_die_horribly(AH, modulename, "COPY failed for table \"%s\": %s",
te->tag, PQerrorMessage(AH->connection));
warn_or_exit_horribly(AH, modulename, "COPY failed for table \"%s\": %s",
te->tag, PQerrorMessage(AH->connection));
PQclear(res);
AH->pgCopyIn = false;
......
......@@ -142,7 +142,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
*/
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;
......@@ -160,9 +160,9 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
tocFH = cfopen_read(fname, PG_BINARY_R);
if (tocFH == NULL)
die_horribly(AH, modulename,
"could not open input file \"%s\": %s\n",
fname, strerror(errno));
exit_horribly(modulename,
"could not open input file \"%s\": %s\n",
fname, strerror(errno));
ctx->dataFH = tocFH;
......@@ -177,7 +177,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
/* Nothing else in the file, so close it again... */
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));
ctx->dataFH = NULL;
}
......@@ -288,8 +288,8 @@ _StartData(ArchiveHandle *AH, TocEntry *te)
ctx->dataFH = cfopen_write(fname, PG_BINARY_W, AH->compression);
if (ctx->dataFH == NULL)
die_horribly(AH, modulename, "could not open output file \"%s\": %s\n",
fname, strerror(errno));
exit_horribly(modulename, "could not open output file \"%s\": %s\n",
fname, strerror(errno));
}
/*
......@@ -346,7 +346,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt)
cfp = cfopen_read(filename, PG_BINARY_R);
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));
buf = pg_malloc(ZLIB_OUT_SIZE);
......@@ -357,7 +357,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt)
free(buf);
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));
}
......@@ -397,8 +397,8 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt)
ctx->blobsTocFH = cfopen_read(fname, PG_BINARY_R);
if (ctx->blobsTocFH == NULL)
die_horribly(AH, modulename, "could not open large object TOC file \"%s\" for input: %s\n",
fname, strerror(errno));
exit_horribly(modulename, "could not open large object TOC file \"%s\" for input: %s\n",
fname, strerror(errno));
/* Read the blobs TOC file line-by-line, and process each blob */
while ((cfgets(ctx->blobsTocFH, line, MAXPGPATH)) != NULL)
......@@ -407,8 +407,8 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt)
char path[MAXPGPATH];
if (sscanf(line, "%u %s\n", &oid, fname) != 2)
die_horribly(AH, modulename, "invalid line in large object TOC file: %s\n",
line);
exit_horribly(modulename, "invalid line in large object TOC file: %s\n",
line);
StartRestoreBlob(AH, oid, ropt->dropSchema);
snprintf(path, MAXPGPATH, "%s/%s", ctx->directory, fname);
......@@ -416,12 +416,12 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt)
EndRestoreBlob(AH, oid);
}
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);
if (cfclose(ctx->blobsTocFH) != 0)
die_horribly(AH, modulename, "could not close large object TOC file \"%s\": %s\n",
fname, strerror(errno));
exit_horribly(modulename, "could not close large object TOC file \"%s\": %s\n",
fname, strerror(errno));
ctx->blobsTocFH = NULL;
......@@ -441,7 +441,7 @@ _WriteByte(ArchiveHandle *AH, const int i)
lclContext *ctx = (lclContext *) AH->formatData;
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;
}
......@@ -460,7 +460,7 @@ _ReadByte(ArchiveHandle *AH)
res = cfgetc(ctx->dataFH);
if (res == EOF)
die_horribly(AH, modulename, "unexpected end of file\n");
exit_horribly(modulename, "unexpected end of file\n");
return res;
}
......@@ -477,7 +477,7 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
res = cfwrite(buf, len, ctx->dataFH);
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));
return res;
......@@ -524,8 +524,8 @@ _CloseArchive(ArchiveHandle *AH)
/* The TOC is always created uncompressed */
tocFH = cfopen_write(fname, PG_BINARY_W, 0);
if (tocFH == NULL)
die_horribly(AH, modulename, "could not open output file \"%s\": %s\n",
fname, strerror(errno));
exit_horribly(modulename, "could not open output file \"%s\": %s\n",
fname, strerror(errno));
ctx->dataFH = tocFH;
/*
......@@ -538,8 +538,8 @@ _CloseArchive(ArchiveHandle *AH)
AH->format = archDirectory;
WriteToc(AH);
if (cfclose(tocFH) != 0)
die_horribly(AH, modulename, "could not close TOC file: %s\n",
strerror(errno));
exit_horribly(modulename, "could not close TOC file: %s\n",
strerror(errno));
WriteDataChunks(AH);
}
AH->FH = NULL;
......@@ -568,8 +568,8 @@ _StartBlobs(ArchiveHandle *AH, TocEntry *te)
/* The blob TOC file is never compressed */
ctx->blobsTocFH = cfopen_write(fname, "ab", 0);
if (ctx->blobsTocFH == NULL)
die_horribly(AH, modulename, "could not open output file \"%s\": %s\n",
fname, strerror(errno));
exit_horribly(modulename, "could not open output file \"%s\": %s\n",
fname, strerror(errno));
}
/*
......@@ -588,7 +588,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
ctx->dataFH = cfopen_write(fname, PG_BINARY_W, AH->compression);
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));
}
......@@ -611,7 +611,7 @@ _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
/* register the blob in blobs.toc */
len = snprintf(buf, sizeof(buf), "%u blob_%u.dat\n", oid, oid);
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)
dname = ctx->directory;
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);
strcat(buf, "/");
......
......@@ -74,7 +74,7 @@ InitArchiveFmt_Null(ArchiveHandle *AH)
* Now prevent reading...
*/
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)
bool old_blob_style = (AH->version < K_VERS_1_12);
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 */
if (old_blob_style && AH->ropt->dropSchema)
......
......@@ -355,7 +355,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
* Couldn't find the requested file. Future: do SEEK(0) and
* 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
{
......@@ -369,7 +369,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
if (AH->compression == 0)
tm->nFH = ctx->tarFH;
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"); */
#else
tm->nFH = ctx->tarFH;
......@@ -411,7 +411,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
#endif
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
......@@ -420,7 +420,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
sprintf(fmode, "wb%d", AH->compression);
tm->zFH = gzdopen(dup(fileno(tm->tmpFH)), fmode);
if (tm->zFH == NULL)
die_horribly(AH, modulename, "could not open temporary file\n");
exit_horribly(modulename, "could not open temporary file\n");
}
else
tm->nFH = tm->tmpFH;
......@@ -447,7 +447,7 @@ tarClose(ArchiveHandle *AH, TAR_MEMBER *th)
*/
if (AH->compression != 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')
_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)
res = fread(&((char *) buf)[used], 1, len, th->nFH);
}
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;
......@@ -584,8 +584,8 @@ tarWrite(const void *buf, size_t len, TAR_MEMBER *th)
res = fwrite(buf, 1, len, th->nFH);
if (res != len)
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));
th->pos += res;
return res;
......@@ -672,8 +672,8 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
* we search the string for it in a paranoid sort of way.
*/
if (strncmp(tmpCopy, "copy ", 5) != 0)
die_horribly(AH, modulename,
"invalid COPY statement -- could not find \"copy\" in string \"%s\"\n", tmpCopy);
exit_horribly(modulename,
"invalid COPY statement -- could not find \"copy\" in string \"%s\"\n", tmpCopy);
pos1 = 5;
for (pos1 = 5; pos1 < strlen(tmpCopy); pos1++)
......@@ -690,9 +690,9 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
break;
if (pos2 >= strlen(tmpCopy))
die_horribly(AH, modulename,
"invalid COPY statement -- could not find \"from stdin\" in string \"%s\" starting at position %lu\n",
tmpCopy, (unsigned long) pos1);
exit_horribly(modulename,
"invalid COPY statement -- could not find \"from stdin\" in string \"%s\" starting at position %lu\n",
tmpCopy, (unsigned long) pos1);
ahwrite(tmpCopy, 1, pos2, AH); /* 'copy "table" [with oids]' */
ahprintf(AH, " from '$$PATH$$/%s' %s", tctx->filename, &tmpCopy[pos2 + 10]);
......@@ -784,7 +784,7 @@ _ReadByte(ArchiveHandle *AH)
res = tarRead(&c, 1, ctx->FH);
if (res != 1)
die_horribly(AH, modulename, "unexpected end of file\n");
exit_horribly(modulename, "unexpected end of file\n");
ctx->filePos += 1;
return c;
}
......@@ -878,7 +878,7 @@ _CloseArchive(ArchiveHandle *AH)
for (i = 0; i < 512; i++)
{
if (fputc(0, ctx->tarFH) == EOF)
die_horribly(AH, modulename,
exit_horribly(modulename,
"could not write null block at end of tar archive\n");
}
}
......@@ -934,7 +934,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
char *sfx;
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)
sfx = ".gz";
......@@ -1077,7 +1077,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
* because pgoff_t can't exceed the compared maximum on their platform.
*/
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);
......@@ -1085,15 +1085,15 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
{
res = fwrite(buf, 1, cnt, th->tarFH);
if (res != cnt)
die_horribly(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));
len += res;
}
if (fclose(tmp) != 0) /* This *should* delete it... */
die_horribly(AH, modulename, "could not close temporary file: %s\n",
strerror(errno));
exit_horribly(modulename, "could not close temporary file: %s\n",
strerror(errno));
if (len != th->fileLen)
{
......@@ -1102,15 +1102,15 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) len);
snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) th->fileLen);
die_horribly(AH, modulename, "actual file length (%s) does not match expected (%s)\n",
buf1, buf2);
exit_horribly(modulename, "actual file length (%s) does not match expected (%s)\n",
buf1, buf2);
}
pad = ((len + 511) & ~511) - len;
for (i = 0; i < pad; i++)
{
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;
......@@ -1159,7 +1159,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
if (!_tarGetHeader(AH, th))
{
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
{
/*
......@@ -1177,9 +1177,9 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
id = atoi(th->targetFile);
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: "
"\"%s\" is required, but comes before \"%s\" in the archive file.\n",
th->targetFile, filename);
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",
th->targetFile, filename);
/* Header doesn't match, so read to next header */
len = ((th->fileLen + 511) & ~511); /* Padded length */
......@@ -1189,7 +1189,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
_tarReadRaw(AH, &header[0], 512, NULL, ctx->tarFH);
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);
......@@ -1222,7 +1222,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) ftello(ctx->tarFH));
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",
buf1, buf2);
}
......@@ -1237,11 +1237,11 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
return 0;
if (len != 512)
die_horribly(AH, modulename,
ngettext("incomplete tar header found (%lu byte)\n",
"incomplete tar header found (%lu bytes)\n",
len),
(unsigned long) len);
exit_horribly(modulename,
ngettext("incomplete tar header found (%lu byte)\n",
"incomplete tar header found (%lu bytes)\n",
len),
(unsigned long) len);
/* Calc checksum */
chk = _tarChecksum(h);
......@@ -1285,10 +1285,10 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
char buf[100];
snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) ftello(ctx->tarFH));
die_horribly(AH, modulename,
"corrupt tar header found in %s "
"(expected %d, computed %d) file position %s\n",
tag, sum, chk, buf);
exit_horribly(modulename,
"corrupt tar header found in %s "
"(expected %d, computed %d) file position %s\n",
tag, sum, chk, buf);
}
th->targetFile = pg_strdup(tag);
......@@ -1379,5 +1379,5 @@ _tarWriteHeader(TAR_MEMBER *th)
}
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;
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,
char *use_role);
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
......@@ -575,7 +574,9 @@ main(int argc, char **argv)
/* Open the output file */
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)
exit_horribly(NULL, "could not open output file \"%s\" for writing\n", filename);
......@@ -836,14 +837,6 @@ help(const char *progname)
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
setup_connection(Archive *AH, const char *dumpencoding, char *use_role)
{
......
......@@ -379,6 +379,13 @@ main(int argc, char **argv)
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 */
AH->verbose = opts->verbose;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册