From e9a22259c45e235aaa30f0d068f767d9c0f818a0 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Thu, 16 Feb 2012 11:49:20 -0500 Subject: [PATCH] Invent on_exit_nicely for pg_dump. Per recent discussions on pgsql-hackers regarding parallel pg_dump. --- src/bin/pg_dump/common.c | 6 +- src/bin/pg_dump/compress_io.c | 27 ++--- src/bin/pg_dump/dumputils.c | 34 +++++- src/bin/pg_dump/dumputils.h | 4 + src/bin/pg_dump/pg_backup.h | 6 +- src/bin/pg_dump/pg_backup_archiver.c | 16 +-- src/bin/pg_dump/pg_backup_db.c | 9 ++ src/bin/pg_dump/pg_backup_directory.c | 17 +-- src/bin/pg_dump/pg_backup_files.c | 16 +-- src/bin/pg_dump/pg_backup_tar.c | 24 ++-- src/bin/pg_dump/pg_dump.c | 151 +++++++++++++------------- src/bin/pg_dump/pg_dump.h | 2 - src/bin/pg_dump/pg_dumpall.c | 48 ++++---- src/bin/pg_dump/pg_restore.c | 18 +-- 14 files changed, 207 insertions(+), 171 deletions(-) diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index 266441df61..db48ccb419 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -770,7 +770,7 @@ findParentsByOid(TableInfo *self, inhinfo[i].inhparent, self->dobj.name, oid); - exit_nicely(); + exit_nicely(1); } self->parents[j++] = parent; } @@ -809,7 +809,7 @@ parseOidArray(const char *str, Oid *array, int arraysize) if (argNum >= arraysize) { write_msg(NULL, "could not parse numeric array \"%s\": too many numbers\n", str); - exit_nicely(); + exit_nicely(1); } temp[j] = '\0'; array[argNum++] = atooid(temp); @@ -824,7 +824,7 @@ parseOidArray(const char *str, Oid *array, int arraysize) j >= sizeof(temp) - 1) { write_msg(NULL, "could not parse numeric array \"%s\": invalid character in number\n", str); - exit_nicely(); + exit_nicely(1); } temp[j++] = s; } diff --git a/src/bin/pg_dump/compress_io.c b/src/bin/pg_dump/compress_io.c index d48b276a06..c30b8f9738 100644 --- a/src/bin/pg_dump/compress_io.c +++ b/src/bin/pg_dump/compress_io.c @@ -54,6 +54,7 @@ #include "compress_io.h" #include "dumpmem.h" +#include "dumputils.h" /*---------------------- * Compressor API @@ -109,8 +110,8 @@ ParseCompressionOption(int compression, CompressionAlgorithm *alg, int *level) *alg = COMPR_ALG_NONE; else { - die_horribly(NULL, modulename, "Invalid compression code: %d\n", - compression); + exit_horribly(modulename, "Invalid compression code: %d\n", + compression); *alg = COMPR_ALG_NONE; /* keep compiler quiet */ } @@ -133,7 +134,7 @@ AllocateCompressor(int compression, WriteFunc writeF) #ifndef HAVE_LIBZ if (alg == COMPR_ALG_LIBZ) - die_horribly(NULL, modulename, "not built with zlib support\n"); + exit_horribly(modulename, "not built with zlib support\n"); #endif cs = (CompressorState *) pg_calloc(1, sizeof(CompressorState)); @@ -169,7 +170,7 @@ ReadDataFromArchive(ArchiveHandle *AH, int compression, ReadFunc readF) #ifdef HAVE_LIBZ ReadDataFromArchiveZlib(AH, readF); #else - die_horribly(NULL, modulename, "not built with zlib support\n"); + exit_horribly(modulename, "not built with zlib support\n"); #endif } } @@ -187,7 +188,7 @@ WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs, #ifdef HAVE_LIBZ return WriteDataToArchiveZlib(AH, cs, data, dLen); #else - die_horribly(NULL, modulename, "not built with zlib support\n"); + exit_horribly(modulename, "not built with zlib support\n"); #endif case COMPR_ALG_NONE: return WriteDataToArchiveNone(AH, cs, data, dLen); @@ -234,9 +235,9 @@ InitCompressorZlib(CompressorState *cs, int level) cs->zlibOutSize = ZLIB_OUT_SIZE; if (deflateInit(zp, level) != Z_OK) - die_horribly(NULL, modulename, - "could not initialize compression library: %s\n", - zp->msg); + exit_horribly(modulename, + "could not initialize compression library: %s\n", + zp->msg); /* Just be paranoid - maybe End is called after Start, with no Write */ zp->next_out = (void *) cs->zlibOut; @@ -343,9 +344,9 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF) out = pg_malloc(ZLIB_OUT_SIZE + 1); if (inflateInit(zp) != Z_OK) - die_horribly(NULL, modulename, - "could not initialize compression library: %s\n", - zp->msg); + exit_horribly(modulename, + "could not initialize compression library: %s\n", + zp->msg); /* no minimal chunk size for zlib */ while ((cnt = readF(AH, &buf, &buflen))) @@ -514,7 +515,7 @@ cfopen_write(const char *path, const char *mode, int compression) fp = cfopen(fname, mode, 1); free(fname); #else - die_horribly(NULL, modulename, "not built with zlib support\n"); + exit_horribly(modulename, "not built with zlib support\n"); fp = NULL; /* keep compiler quiet */ #endif } @@ -541,7 +542,7 @@ cfopen(const char *path, const char *mode, int compression) fp = NULL; } #else - die_horribly(NULL, modulename, "not built with zlib support\n"); + exit_horribly(modulename, "not built with zlib support\n"); #endif } else diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index 3493e39403..0b24220bd4 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -26,6 +26,15 @@ int quote_all_identifiers = 0; const char *progname = NULL; +#define MAX_ON_EXIT_NICELY 20 + +static struct +{ + on_exit_nicely_callback function; + void *arg; +} on_exit_nicely_list[MAX_ON_EXIT_NICELY]; + +static int on_exit_nicely_index; #define supports_grant_options(version) ((version) >= 70400) @@ -1261,7 +1270,7 @@ exit_horribly(const char *modulename, const char *fmt,...) vwrite_msg(modulename, fmt, ap); va_end(ap); - exit(1); + exit_nicely(1); } /* @@ -1289,6 +1298,27 @@ set_section (const char *arg, int *dumpSections) progname, arg); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } } + +/* Register a callback to be run when exit_nicely is invoked. */ +void +on_exit_nicely(on_exit_nicely_callback function, void *arg) +{ + if (on_exit_nicely_index >= MAX_ON_EXIT_NICELY) + exit_horribly(NULL, "out of on_exit_nicely slots"); + on_exit_nicely_list[on_exit_nicely_index].function = function; + on_exit_nicely_list[on_exit_nicely_index].arg = arg; + on_exit_nicely_index++; +} + +/* Run accumulated on_exit_nicely callbacks and then exit quietly. */ +void +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); + exit(code); +} diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h index de1536baaa..82cf940892 100644 --- a/src/bin/pg_dump/dumputils.h +++ b/src/bin/pg_dump/dumputils.h @@ -60,4 +60,8 @@ extern void exit_horribly(const char *modulename, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn)); extern void set_section (const char *arg, int *dumpSections); +typedef void (*on_exit_nicely_callback) (int code, void *arg); +extern void on_exit_nicely(on_exit_nicely_callback function, void *arg); +extern void exit_nicely(int code) __attribute__((noreturn)); + #endif /* DUMPUTILS_H */ diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h index 0eef1dc8ba..d12bd7fa79 100644 --- a/src/bin/pg_dump/pg_backup.h +++ b/src/bin/pg_dump/pg_backup.h @@ -159,15 +159,13 @@ typedef struct _restoreOptions * Main archiver interface. */ - -/* Lets the archive know we have a DB connection to shutdown if it dies */ - -PGconn *ConnectDatabase(Archive *AH, +extern PGconn *ConnectDatabase(Archive *AH, const char *dbname, const char *pghost, const char *pgport, const char *username, enum trivalue prompt_password); +extern void DisconnectDatabase(Archive *AHX); /* Called to add a TOC entry */ extern void ArchiveEntry(Archive *AHX, diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 44ba913d4a..55c84fdd47 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -459,10 +459,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) RestoreOutput(AH, sav); if (ropt->useDB) - { - PQfinish(AH->connection); - AH->connection = NULL; - } + DisconnectDatabase(&AH->public); } /* @@ -1435,11 +1432,10 @@ vdie_horribly(ArchiveHandle *AH, const char *modulename, { if (AH->public.verbose) write_msg(NULL, "*** aborted because of error\n"); - if (AH->connection) - PQfinish(AH->connection); + DisconnectDatabase(&AH->public); } - exit(1); + exit_nicely(1); } /* As above, but with variable arg list */ @@ -3332,8 +3328,7 @@ restore_toc_entries_parallel(ArchiveHandle *AH) * mainly to ensure that we don't exceed the specified number of parallel * connections. */ - PQfinish(AH->connection); - AH->connection = NULL; + DisconnectDatabase(&AH->public); /* blow away any transient state from the old connection */ if (AH->currUser) @@ -3795,8 +3790,7 @@ parallel_restore(RestoreArgs *args) retval = restore_toc_entry(AH, te, ropt, true); /* And clean up */ - PQfinish(AH->connection); - AH->connection = NULL; + DisconnectDatabase((Archive *) AH); /* If we reopened the file, we are done with it, so close it now */ if (te->section == SECTION_DATA) diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index 09da892597..31f6d8d94d 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -310,6 +310,15 @@ ConnectDatabase(Archive *AHX, return AH->connection; } +void +DisconnectDatabase(Archive *AHX) +{ + ArchiveHandle *AH = (ArchiveHandle *) AHX; + + PQfinish(AH->connection); /* noop if AH->connection is NULL */ + AH->connection = NULL; +} + static void notice_processor(void *arg, const char *message) diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c index 9c6d7c1b6d..df95411cfd 100644 --- a/src/bin/pg_dump/pg_backup_directory.c +++ b/src/bin/pg_dump/pg_backup_directory.c @@ -35,6 +35,7 @@ #include "compress_io.h" #include "dumpmem.h" +#include "dumputils.h" #include #include @@ -633,13 +634,13 @@ createDirectory(const char *dir) if (stat(dir, &st) == 0) { if (S_ISDIR(st.st_mode)) - die_horribly(NULL, modulename, - "cannot create directory %s, it exists already\n", - dir); + exit_horribly(modulename, + "cannot create directory %s, it exists already\n", + dir); else - die_horribly(NULL, modulename, - "cannot create directory %s, a file with this name " - "exists already\n", dir); + exit_horribly(modulename, + "cannot create directory %s, a file with this name " + "exists already\n", dir); } /* @@ -648,8 +649,8 @@ createDirectory(const char *dir) * between our two calls. */ if (mkdir(dir, 0700) < 0) - die_horribly(NULL, modulename, "could not create directory %s: %s", - dir, strerror(errno)); + exit_horribly(modulename, "could not create directory %s: %s", + dir, strerror(errno)); } diff --git a/src/bin/pg_dump/pg_backup_files.c b/src/bin/pg_dump/pg_backup_files.c index ffcbb8f642..71bace0eab 100644 --- a/src/bin/pg_dump/pg_backup_files.c +++ b/src/bin/pg_dump/pg_backup_files.c @@ -127,15 +127,15 @@ InitArchiveFmt_Files(ArchiveHandle *AH) { AH->FH = fopen(AH->fSpec, PG_BINARY_W); if (AH->FH == NULL) - die_horribly(NULL, 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 == NULL) - die_horribly(NULL, 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); @@ -152,15 +152,15 @@ InitArchiveFmt_Files(ArchiveHandle *AH) { AH->FH = fopen(AH->fSpec, PG_BINARY_R); if (AH->FH == NULL) - die_horribly(NULL, 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 == NULL) - die_horribly(NULL, 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); diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c index 39ce417d86..4952f5a15d 100644 --- a/src/bin/pg_dump/pg_backup_tar.c +++ b/src/bin/pg_dump/pg_backup_tar.c @@ -29,6 +29,7 @@ #include "pg_backup_archiver.h" #include "pg_backup_tar.h" #include "dumpmem.h" +#include "dumputils.h" #include #include @@ -178,17 +179,17 @@ InitArchiveFmt_Tar(ArchiveHandle *AH) { ctx->tarFH = fopen(AH->fSpec, PG_BINARY_W); if (ctx->tarFH == NULL) - die_horribly(NULL, modulename, - "could not open TOC file \"%s\" for output: %s\n", - AH->fSpec, strerror(errno)); + exit_horribly(modulename, + "could not open TOC file \"%s\" for output: %s\n", + AH->fSpec, strerror(errno)); } else { ctx->tarFH = stdout; if (ctx->tarFH == NULL) - die_horribly(NULL, modulename, - "could not open TOC file for output: %s\n", - strerror(errno)); + exit_horribly(modulename, + "could not open TOC file for output: %s\n", + strerror(errno)); } ctx->tarFHpos = 0; @@ -214,7 +215,8 @@ InitArchiveFmt_Tar(ArchiveHandle *AH) * positioning. */ if (AH->compression != 0) - die_horribly(NULL, modulename, "compression is not supported by tar archive format\n"); + exit_horribly(modulename, + "compression is not supported by tar archive format\n"); } else { /* Read Mode */ @@ -222,15 +224,15 @@ InitArchiveFmt_Tar(ArchiveHandle *AH) { ctx->tarFH = fopen(AH->fSpec, PG_BINARY_R); if (ctx->tarFH == NULL) - die_horribly(NULL, modulename, "could not open TOC file \"%s\" for input: %s\n", - AH->fSpec, strerror(errno)); + exit_horribly(modulename, "could not open TOC file \"%s\" for input: %s\n", + AH->fSpec, strerror(errno)); } else { ctx->tarFH = stdin; if (ctx->tarFH == NULL) - die_horribly(NULL, modulename, "could not open TOC file for input: %s\n", - strerror(errno)); + exit_horribly(modulename, "could not open TOC file for input: %s\n", + strerror(errno)); } /* diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index f968496aaa..6eddc63e28 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -145,6 +145,7 @@ 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); @@ -370,12 +371,12 @@ main(int argc, char **argv) if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { help(progname); - exit(0); + exit_nicely(0); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { puts("pg_dump (PostgreSQL) " PG_VERSION); - exit(0); + exit_nicely(0); } } @@ -508,7 +509,7 @@ main(int argc, char **argv) default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } } @@ -523,7 +524,7 @@ main(int argc, char **argv) progname, argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } /* --column-inserts implies --inserts */ @@ -533,13 +534,13 @@ main(int argc, char **argv) if (dataOnly && schemaOnly) { write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n"); - exit(1); + exit_nicely(1); } if ((dataOnly || schemaOnly) && dumpSections != DUMP_UNSECTIONED) { write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used with --section\n"); - exit(1); + exit_nicely(1); } if (dataOnly) @@ -555,14 +556,14 @@ main(int argc, char **argv) if (dataOnly && outputClean) { write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n"); - exit(1); + exit_nicely(1); } if (dump_inserts && oids) { write_msg(NULL, "options --inserts/--column-inserts and -o/--oids cannot be used together\n"); write_msg(NULL, "(The INSERT command cannot set OIDs.)\n"); - exit(1); + exit_nicely(1); } /* Identify archive format to emit */ @@ -583,11 +584,12 @@ main(int argc, char **argv) /* Open the output file */ fout = CreateArchive(filename, archiveFormat, compressLevel, archiveMode); + on_exit_nicely(pgdump_cleanup_at_exit, fout); if (fout == NULL) { write_msg(NULL, "could not open output file \"%s\" for writing\n", filename); - exit(1); + exit_nicely(1); } /* Let the archiver know how noisy to be */ @@ -597,7 +599,7 @@ main(int argc, char **argv) if (my_version < 0) { write_msg(NULL, "could not parse version string \"%s\"\n", PG_VERSION); - exit(1); + exit_nicely(1); } /* @@ -669,7 +671,7 @@ main(int argc, char **argv) if (schema_include_oids.head == NULL) { write_msg(NULL, "No matching schemas were found\n"); - exit_nicely(); + exit_nicely(1); } } expand_schema_name_patterns(fout, &schema_exclude_patterns, @@ -684,7 +686,7 @@ main(int argc, char **argv) if (table_include_oids.head == NULL) { write_msg(NULL, "No matching tables were found\n"); - exit_nicely(); + exit_nicely(1); } } expand_table_name_patterns(fout, &table_exclude_patterns, @@ -790,9 +792,7 @@ main(int argc, char **argv) CloseArchive(fout); - PQfinish(g_conn); - - exit(0); + exit_nicely(0); } @@ -858,13 +858,12 @@ help(const char *progname) printf(_("Report bugs to .\n")); } -void -exit_nicely(void) +static void +pgdump_cleanup_at_exit(int code, void *arg) { - PQfinish(g_conn); - if (g_verbose) - write_msg(NULL, "*** aborted because of error\n"); - exit(1); + Archive *AH = (Archive *) arg; + + DisconnectDatabase(AH); } static void @@ -879,7 +878,7 @@ setup_connection(Archive *AH, const char *dumpencoding, char *use_role) { write_msg(NULL, "invalid client encoding \"%s\" specified\n", dumpencoding); - exit(1); + exit_nicely(1); } } @@ -977,7 +976,7 @@ parseArchiveFormat(const char *format, ArchiveMode *mode) else { write_msg(NULL, "invalid output format \"%s\" specified\n", format); - exit(1); + exit_nicely(1); } return archiveFormat; } @@ -1002,7 +1001,7 @@ expand_schema_name_patterns(Archive *fout, if (fout->remoteVersion < 70300) { write_msg(NULL, "server version must be at least 7.3 to use schema selection switches\n"); - exit_nicely(); + exit_nicely(1); } query = createPQExpBuffer(); @@ -1397,7 +1396,7 @@ dumpTableData_copy(Archive *fout, void *dcontext) write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n", classname); write_msg(NULL, "Error message from server: %s", PQerrorMessage(g_conn)); write_msg(NULL, "The command was: %s\n", q->data); - exit_nicely(); + exit_nicely(1); } /* Check command status and return to normal libpq state */ @@ -1407,7 +1406,7 @@ dumpTableData_copy(Archive *fout, void *dcontext) write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n", classname); write_msg(NULL, "Error message from server: %s", PQerrorMessage(g_conn)); write_msg(NULL, "The command was: %s\n", q->data); - exit_nicely(); + exit_nicely(1); } PQclear(res); @@ -1936,14 +1935,14 @@ dumpDatabase(Archive *fout) { write_msg(NULL, "missing pg_database entry for database \"%s\"\n", datname); - exit_nicely(); + exit_nicely(1); } if (ntups != 1) { write_msg(NULL, "query returned more than one (%d) pg_database entry for database \"%s\"\n", ntups, datname); - exit_nicely(); + exit_nicely(1); } i_tableoid = PQfnumber(res, "tableoid"); @@ -2045,7 +2044,7 @@ dumpDatabase(Archive *fout) if (PQntuples(lo_res) != 1) { write_msg(NULL, "dumpDatabase(): could not find pg_largeobject.relfrozenxid\n"); - exit_nicely(); + exit_nicely(1); } i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid"); @@ -2083,7 +2082,7 @@ dumpDatabase(Archive *fout) if (PQntuples(lo_res) != 1) { write_msg(NULL, "dumpDatabase(): could not find pg_largeobject_metadata.relfrozenxid\n"); - exit_nicely(); + exit_nicely(1); } i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid"); @@ -2409,7 +2408,7 @@ dumpBlobs(Archive *fout, void *arg) { write_msg(NULL, "could not open large object %u: %s", blobOid, PQerrorMessage(g_conn)); - exit_nicely(); + exit_nicely(1); } StartBlob(fout, blobOid); @@ -2422,7 +2421,7 @@ dumpBlobs(Archive *fout, void *arg) { write_msg(NULL, "error reading large object %u: %s", blobOid, PQerrorMessage(g_conn)); - exit_nicely(); + exit_nicely(1); } WriteData(fout, buf, cnt); @@ -2473,7 +2472,7 @@ binary_upgrade_set_type_oids_by_type_oid(Archive *fout, "query returned %d rows instead of one: %s\n", ntups), ntups, upgrade_query->data); - exit_nicely(); + exit_nicely(1); } pg_type_array_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "typarray"))); @@ -2521,7 +2520,7 @@ binary_upgrade_set_type_oids_by_rel_oid(Archive *fout, "query returned %d rows instead of one: %s\n", ntups), ntups, upgrade_query->data); - exit_nicely(); + exit_nicely(1); } pg_type_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "crel"))); @@ -2577,7 +2576,7 @@ binary_upgrade_set_pg_class_oids(Archive *fout, "query returned %d rows instead of one: %s\n", ntups), ntups, upgrade_query->data); - exit_nicely(); + exit_nicely(1); } pg_class_reltoastrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastrelid"))); @@ -2655,7 +2654,7 @@ binary_upgrade_extension_member(PQExpBuffer upgrade_buffer, if (extobj == NULL) { write_msg(NULL, "could not find parent extension for %s", objlabel); - exit_nicely(); + exit_nicely(1); } appendPQExpBuffer(upgrade_buffer, @@ -2796,7 +2795,7 @@ findNamespace(Archive *fout, Oid nsoid, Oid objoid) return nsinfo; } write_msg(NULL, "schema with OID %u does not exist\n", nsoid); - exit_nicely(); + exit_nicely(1); } else { @@ -5124,7 +5123,7 @@ getRules(Archive *fout, int *numRules) write_msg(NULL, "failed sanity check, parent table OID %u of pg_rewrite entry OID %u not found\n", ruletableoid, ruleinfo[i].dobj.catId.oid); - exit_nicely(); + exit_nicely(1); } ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace; ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump; @@ -5370,7 +5369,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables) write_msg(NULL, "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n", tginfo[j].dobj.name, tbinfo->dobj.name, tginfo[j].tgconstrrelid); - exit_nicely(); + exit_nicely(1); } tginfo[j].tgconstrrelname = pg_strdup(PQgetvalue(res, j, i_tgconstrrelname)); } @@ -5917,7 +5916,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) { write_msg(NULL, "invalid column numbering in table \"%s\"\n", tbinfo->dobj.name); - exit_nicely(); + exit_nicely(1); } tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, j, i_attname)); tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, j, i_atttypname)); @@ -6005,7 +6004,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) { write_msg(NULL, "invalid adnum value %d for table \"%s\"\n", adnum, tbinfo->dobj.name); - exit_nicely(); + exit_nicely(1); } /* @@ -6182,7 +6181,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) tbinfo->ncheck), tbinfo->ncheck, tbinfo->dobj.name, numConstrs); write_msg(NULL, "(The system catalogs might be corrupted.)\n"); - exit_nicely(); + exit_nicely(1); } constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo)); @@ -7706,7 +7705,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo) { write_msg(NULL, "query returned %d pg_range entries for range type \"%s\"\n", PQntuples(res), tyinfo->dobj.name); - exit_nicely(); + exit_nicely(1); } /* @@ -8019,7 +8018,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen")); @@ -8250,7 +8249,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull")); @@ -9242,7 +9241,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset")); @@ -9420,7 +9419,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) { write_msg(NULL, "unrecognized provolatile value for function \"%s\"\n", finfo->dobj.name); - exit_nicely(); + exit_nicely(1); } } @@ -9799,7 +9798,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } i_oprkind = PQfnumber(res, "oprkind"); @@ -10052,7 +10051,7 @@ convertTSFunction(Archive *fout, Oid funcOid) "query returned %d rows instead of one: %s\n", ntups), ntups, query); - exit_nicely(); + exit_nicely(1); } result = pg_strdup(PQgetvalue(res, 0, 0)); @@ -10169,7 +10168,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } i_opcintype = PQfnumber(res, "opcintype"); @@ -10637,7 +10636,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } i_amname = PQfnumber(res, "amname"); @@ -10822,7 +10821,7 @@ dumpCollation(Archive *fout, CollInfo *collinfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } i_collcollate = PQfnumber(res, "collcollate"); @@ -10927,7 +10926,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } i_conforencoding = PQfnumber(res, "conforencoding"); @@ -11127,7 +11126,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } i_aggtransfn = PQfnumber(res, "aggtransfn"); @@ -11368,7 +11367,7 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } nspname = PQgetvalue(res, 0, 0); tmplname = PQgetvalue(res, 0, 1); @@ -11534,7 +11533,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } nspname = PQgetvalue(res, 0, 0); prsname = PQgetvalue(res, 0, 1); @@ -11753,7 +11752,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } fdwname = PQgetvalue(res, 0, 0); @@ -11952,7 +11951,7 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo) /* shouldn't get here */ write_msg(NULL, "unknown object type (%d) in default privileges\n", (int) daclinfo->defaclobjtype); - exit_nicely(); + exit_nicely(1); type = ""; /* keep compiler quiet */ } @@ -11969,7 +11968,7 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo) { write_msg(NULL, "could not parse default ACL list (%s)\n", daclinfo->defaclacl); - exit_nicely(); + exit_nicely(1); } ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId, @@ -12026,7 +12025,7 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId, { write_msg(NULL, "could not parse ACL list (%s) for object \"%s\" (%s)\n", acls, name, type); - exit_nicely(); + exit_nicely(1); } if (sql->len > 0) @@ -12472,7 +12471,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) else write_msg(NULL, "query to obtain definition of view \"%s\" returned more than one definition\n", tbinfo->dobj.name); - exit_nicely(); + exit_nicely(1); } viewdef = PQgetvalue(res, 0, 0); @@ -12481,7 +12480,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) { write_msg(NULL, "definition of view \"%s\" appears to be empty (length zero)\n", tbinfo->dobj.name); - exit_nicely(); + exit_nicely(1); } /* @@ -12537,7 +12536,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) "query returned %d foreign server entries for foreign table \"%s\"\n", PQntuples(res)), PQntuples(res), tbinfo->dobj.name); - exit_nicely(); + exit_nicely(1); } i_srvname = PQfnumber(res, "srvname"); i_ftoptions = PQfnumber(res, "ftoptions"); @@ -13102,7 +13101,7 @@ getAttrName(int attrnum, TableInfo *tblInfo) } write_msg(NULL, "invalid column number %d for table \"%s\"\n", attrnum, tblInfo->dobj.name); - exit_nicely(); + exit_nicely(1); return NULL; /* keep compiler quiet */ } @@ -13214,7 +13213,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) { write_msg(NULL, "missing index for constraint \"%s\"\n", coninfo->dobj.name); - exit_nicely(); + exit_nicely(1); } if (binary_upgrade) @@ -13402,7 +13401,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) else { write_msg(NULL, "unrecognized constraint type: %c\n", coninfo->contype); - exit_nicely(); + exit_nicely(1); } /* Dump Constraint Comments --- only works for table constraints */ @@ -13464,12 +13463,12 @@ findLastBuiltinOid_V71(Archive *fout, const char *dbname) if (ntups < 1) { write_msg(NULL, "missing pg_database entry for this database\n"); - exit_nicely(); + exit_nicely(1); } if (ntups > 1) { write_msg(NULL, "found more than one pg_database entry for this database\n"); - exit_nicely(); + exit_nicely(1); } last_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "datlastsysoid"))); PQclear(res); @@ -13499,12 +13498,12 @@ findLastBuiltinOid_V70(Archive *fout) if (ntups < 1) { write_msg(NULL, "could not find entry for pg_indexes in pg_class\n"); - exit_nicely(); + exit_nicely(1); } if (ntups > 1) { write_msg(NULL, "found more than one entry for pg_indexes in pg_class\n"); - exit_nicely(); + exit_nicely(1); } last_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid"))); PQclear(res); @@ -13578,7 +13577,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo) "query to get data of sequence \"%s\" returned %d rows (expected 1)\n", PQntuples(res)), tbinfo->dobj.name, PQntuples(res)); - exit_nicely(); + exit_nicely(1); } /* Disable this check: it fails if sequence has been renamed */ @@ -13587,7 +13586,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo) { write_msg(NULL, "query to get data of sequence \"%s\" returned name \"%s\"\n", tbinfo->dobj.name, PQgetvalue(res, 0, 0)); - exit_nicely(); + exit_nicely(1); } #endif @@ -13816,7 +13815,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) else { write_msg(NULL, "unexpected tgtype value: %d\n", tginfo->tgtype); - exit_nicely(); + exit_nicely(1); } findx = 0; @@ -13901,7 +13900,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) tginfo->tgargs, tginfo->dobj.name, tbinfo->dobj.name); - exit_nicely(); + exit_nicely(1); } if (findx > 0) @@ -14016,7 +14015,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo) { write_msg(NULL, "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n", rinfo->dobj.name, tbinfo->dobj.name); - exit_nicely(); + exit_nicely(1); } printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0)); @@ -14474,7 +14473,7 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts) "query returned %d rows instead of one: %s\n", ntups), ntups, query->data); - exit_nicely(); + exit_nicely(1); } if (fout->remoteVersion >= 70100) diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 421847e5d5..28a7fe4e13 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -518,8 +518,6 @@ extern void simple_string_list_append(SimpleStringList *list, const char *val); extern bool simple_oid_list_member(SimpleOidList *list, Oid val); extern bool simple_string_list_member(SimpleStringList *list, const char *val); -extern void exit_nicely(void) __attribute__((noreturn)); - extern void parseOidArray(const char *str, Oid *array, int arraysize); extern void sortDumpableObjects(DumpableObject **objs, int numObjs); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 4c9366738a..4f8dd60068 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -151,12 +151,12 @@ main(int argc, char *argv[]) if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { help(); - exit(0); + exit_nicely(0); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { puts("pg_dumpall (PostgreSQL) " PG_VERSION); - exit(0); + exit_nicely(0); } } @@ -181,7 +181,7 @@ main(int argc, char *argv[]) "but was not the same version as %s.\n" "Check your installation.\n"), full_path, progname); - exit(1); + exit_nicely(1); } pgdumpopts = createPQExpBuffer(); @@ -296,7 +296,7 @@ main(int argc, char *argv[]) default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } } @@ -307,7 +307,7 @@ main(int argc, char *argv[]) progname, argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } /* Make sure the user hasn't specified a mix of globals-only options */ @@ -317,7 +317,7 @@ main(int argc, char *argv[]) progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } if (globals_only && tablespaces_only) @@ -326,7 +326,7 @@ main(int argc, char *argv[]) progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } if (roles_only && tablespaces_only) @@ -335,7 +335,7 @@ main(int argc, char *argv[]) progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } /* Add long options to the pg_dump argument list */ @@ -375,7 +375,7 @@ main(int argc, char *argv[]) { fprintf(stderr, _("%s: could not connect to database \"%s\"\n"), progname, pgdb); - exit(1); + exit_nicely(1); } } else @@ -393,7 +393,7 @@ main(int argc, char *argv[]) progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } } @@ -407,7 +407,7 @@ main(int argc, char *argv[]) { fprintf(stderr, _("%s: could not open the output file \"%s\": %s\n"), progname, filename, strerror(errno)); - exit(1); + exit_nicely(1); } } else @@ -525,7 +525,7 @@ main(int argc, char *argv[]) if (filename) fclose(OPF); - exit(0); + exit_nicely(0); } @@ -1068,7 +1068,7 @@ dumpTablespaces(PGconn *conn) fprintf(stderr, _("%s: could not parse ACL list (%s) for tablespace \"%s\"\n"), progname, spcacl, fspcname); PQfinish(conn); - exit(1); + exit_nicely(1); } if (spccomment && strlen(spccomment)) @@ -1372,7 +1372,7 @@ dumpCreateDB(PGconn *conn) fprintf(stderr, _("%s: could not parse ACL list (%s) for database \"%s\"\n"), progname, dbacl, fdbname); PQfinish(conn); - exit(1); + exit_nicely(1); } fprintf(OPF, "%s", buf->data); @@ -1587,7 +1587,7 @@ dumpDatabases(PGconn *conn) if (ret != 0) { fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname); - exit(1); + exit_nicely(1); } if (filename) @@ -1597,7 +1597,7 @@ dumpDatabases(PGconn *conn) { fprintf(stderr, _("%s: could not re-open the output file \"%s\": %s\n"), progname, filename, strerror(errno)); - exit(1); + exit_nicely(1); } } @@ -1724,7 +1724,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, { fprintf(stderr, _("%s: could not connect to database \"%s\"\n"), progname, dbname); - exit(1); + exit_nicely(1); } if (PQstatus(conn) == CONNECTION_BAD && @@ -1746,7 +1746,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, fprintf(stderr, _("%s: could not connect to database \"%s\": %s\n"), progname, dbname, PQerrorMessage(conn)); - exit(1); + exit_nicely(1); } else { @@ -1759,14 +1759,14 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, if (!remoteversion_str) { fprintf(stderr, _("%s: could not get server version\n"), progname); - exit(1); + exit_nicely(1); } server_version = parse_version(remoteversion_str); if (server_version < 0) { fprintf(stderr, _("%s: could not parse server version \"%s\"\n"), progname, remoteversion_str); - exit(1); + exit_nicely(1); } my_version = parse_version(PG_VERSION); @@ -1774,7 +1774,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, { fprintf(stderr, _("%s: could not parse version \"%s\"\n"), progname, PG_VERSION); - exit(1); + exit_nicely(1); } /* @@ -1788,7 +1788,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, fprintf(stderr, _("server version: %s; %s version: %s\n"), remoteversion_str, progname, PG_VERSION); fprintf(stderr, _("aborting because of server version mismatch\n")); - exit(1); + exit_nicely(1); } /* @@ -1822,7 +1822,7 @@ executeQuery(PGconn *conn, const char *query) fprintf(stderr, _("%s: query was: %s\n"), progname, query); PQfinish(conn); - exit(1); + exit_nicely(1); } return res; @@ -1848,7 +1848,7 @@ executeCommand(PGconn *conn, const char *query) fprintf(stderr, _("%s: query was: %s\n"), progname, query); PQfinish(conn); - exit(1); + exit_nicely(1); } PQclear(res); diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 6ff1ab8904..1c026cf91a 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -138,12 +138,12 @@ main(int argc, char **argv) if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { usage(progname); - exit(0); + exit_nicely(0); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { puts("pg_restore (PostgreSQL) " PG_VERSION); - exit(0); + exit_nicely(0); } } @@ -279,7 +279,7 @@ main(int argc, char **argv) default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } } @@ -296,21 +296,21 @@ main(int argc, char **argv) progname, argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } if (opts->dataOnly && opts->schemaOnly) { fprintf(stderr, _("%s: options -s/--schema-only and -a/--data-only cannot be used together\n"), progname); - exit(1); + exit_nicely(1); } if ((opts->dataOnly || opts->schemaOnly) && (opts->dumpSections != DUMP_UNSECTIONED)) { fprintf(stderr, _("%s: options -s/--schema-only and -a/--data-only cannot be used with --section\n"), progname); - exit(1); + exit_nicely(1); } if (opts->dataOnly) @@ -332,7 +332,7 @@ main(int argc, char **argv) progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + exit_nicely(1); } opts->useDB = 1; } @@ -342,7 +342,7 @@ main(int argc, char **argv) { fprintf(stderr, _("%s: cannot specify both --single-transaction and multiple jobs\n"), progname); - exit(1); + exit_nicely(1); } opts->disable_triggers = disable_triggers; @@ -378,7 +378,7 @@ main(int argc, char **argv) default: write_msg(NULL, "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"\n", opts->formatName); - exit(1); + exit_nicely(1); } }