From 44096f1c6644a97c92da6c96dc1d8d4e200d4a38 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 11 Jan 2015 13:28:26 -0500 Subject: [PATCH] Fix portability breakage in pg_dump. Commit 0eea8047bf0e15b402b951e383e39236bdfe57d5 introduced some overly optimistic assumptions about what could be in a local struct variable's initializer. (This might in fact be valid code according to C99, but I've got at least one pre-C99 compiler that falls over on those nonconstant address expressions.) There is no reason whatsoever for main()'s workspace to not be static, so revert long_options[] to a static and make the DumpOptions struct static as well. --- src/bin/pg_dump/pg_backup.h | 1 + src/bin/pg_dump/pg_backup_archiver.c | 20 ++-- src/bin/pg_dump/pg_dump.c | 154 ++++++++++++++------------- 3 files changed, 91 insertions(+), 84 deletions(-) diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h index c2ebcd4f74..a936ff81b9 100644 --- a/src/bin/pg_dump/pg_backup.h +++ b/src/bin/pg_dump/pg_backup.h @@ -269,6 +269,7 @@ extern void PrintTOCSummary(Archive *AH, RestoreOptions *ropt); extern RestoreOptions *NewRestoreOptions(void); extern DumpOptions *NewDumpOptions(void); +extern void InitDumpOptions(DumpOptions *opts); extern DumpOptions *dumpOptionsFromRestoreOptions(RestoreOptions *ropt); /* Rearrange and filter TOC entries */ diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 43065e84b2..9e6455861d 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -109,23 +109,27 @@ static void mark_create_done(ArchiveHandle *AH, TocEntry *te); static void inhibit_data_for_failed_table(ArchiveHandle *AH, TocEntry *te); /* - * Allocate a new DumpOptions block. - * This is mainly so we can initialize it, but also for future expansion. - * We pg_malloc0 the structure, so we don't need to initialize whatever is - * 0, NULL or false anyway. + * Allocate a new DumpOptions block containing all default values. */ DumpOptions * NewDumpOptions(void) { - DumpOptions *opts; + DumpOptions *opts = (DumpOptions *) pg_malloc(sizeof(DumpOptions)); - opts = (DumpOptions *) pg_malloc0(sizeof(DumpOptions)); + InitDumpOptions(opts); + return opts; +} +/* + * Initialize a DumpOptions struct to all default values + */ +void +InitDumpOptions(DumpOptions *opts) +{ + memset(opts, 0, sizeof(DumpOptions)); /* set any fields that shouldn't default to zeroes */ opts->include_everything = true; opts->dumpSections = DUMP_UNSECTIONED; - - return opts; } /* diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 981fdf149e..dc062e67ee 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -279,9 +279,9 @@ main(int argc, char **argv) ArchiveFormat archiveFormat = archUnknown; ArchiveMode archiveMode; - DumpOptions *dopt = NewDumpOptions(); + static DumpOptions dopt; - struct option long_options[] = { + static struct option long_options[] = { {"data-only", no_argument, NULL, 'a'}, {"blobs", no_argument, NULL, 'b'}, {"clean", no_argument, NULL, 'c'}, @@ -316,26 +316,26 @@ main(int argc, char **argv) /* * the following options don't have an equivalent short option letter */ - {"attribute-inserts", no_argument, &dopt->column_inserts, 1}, - {"binary-upgrade", no_argument, &dopt->binary_upgrade, 1}, - {"column-inserts", no_argument, &dopt->column_inserts, 1}, - {"disable-dollar-quoting", no_argument, &dopt->disable_dollar_quoting, 1}, - {"disable-triggers", no_argument, &dopt->disable_triggers, 1}, - {"enable-row-security", no_argument, &dopt->enable_row_security, 1}, + {"attribute-inserts", no_argument, &dopt.column_inserts, 1}, + {"binary-upgrade", no_argument, &dopt.binary_upgrade, 1}, + {"column-inserts", no_argument, &dopt.column_inserts, 1}, + {"disable-dollar-quoting", no_argument, &dopt.disable_dollar_quoting, 1}, + {"disable-triggers", no_argument, &dopt.disable_triggers, 1}, + {"enable-row-security", no_argument, &dopt.enable_row_security, 1}, {"exclude-table-data", required_argument, NULL, 4}, - {"if-exists", no_argument, &dopt->if_exists, 1}, - {"inserts", no_argument, &dopt->dump_inserts, 1}, + {"if-exists", no_argument, &dopt.if_exists, 1}, + {"inserts", no_argument, &dopt.dump_inserts, 1}, {"lock-wait-timeout", required_argument, NULL, 2}, - {"no-tablespaces", no_argument, &dopt->outputNoTablespaces, 1}, + {"no-tablespaces", no_argument, &dopt.outputNoTablespaces, 1}, {"quote-all-identifiers", no_argument, "e_all_identifiers, 1}, {"role", required_argument, NULL, 3}, {"section", required_argument, NULL, 5}, - {"serializable-deferrable", no_argument, &dopt->serializable_deferrable, 1}, + {"serializable-deferrable", no_argument, &dopt.serializable_deferrable, 1}, {"snapshot", required_argument, NULL, 6}, - {"use-set-session-authorization", no_argument, &dopt->use_setsessauth, 1}, - {"no-security-labels", no_argument, &dopt->no_security_labels, 1}, - {"no-synchronized-snapshots", no_argument, &dopt->no_synchronized_snapshots, 1}, - {"no-unlogged-table-data", no_argument, &dopt->no_unlogged_table_data, 1}, + {"use-set-session-authorization", no_argument, &dopt.use_setsessauth, 1}, + {"no-security-labels", no_argument, &dopt.no_security_labels, 1}, + {"no-synchronized-snapshots", no_argument, &dopt.no_synchronized_snapshots, 1}, + {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1}, {NULL, 0, NULL, 0} }; @@ -374,29 +374,31 @@ main(int argc, char **argv) } } + InitDumpOptions(&dopt); + while ((c = getopt_long(argc, argv, "abcCd:E:f:F:h:ij:n:N:oOp:RsS:t:T:U:vwWxZ:", long_options, &optindex)) != -1) { switch (c) { case 'a': /* Dump data only */ - dopt->dataOnly = true; + dopt.dataOnly = true; break; case 'b': /* Dump blobs */ - dopt->outputBlobs = true; + dopt.outputBlobs = true; break; case 'c': /* clean (i.e., drop) schema prior to create */ - dopt->outputClean = 1; + dopt.outputClean = 1; break; case 'C': /* Create DB */ - dopt->outputCreateDB = 1; + dopt.outputCreateDB = 1; break; case 'd': /* database name */ - dopt->dbname = pg_strdup(optarg); + dopt.dbname = pg_strdup(optarg); break; case 'E': /* Dump encoding */ @@ -412,7 +414,7 @@ main(int argc, char **argv) break; case 'h': /* server host */ - dopt->pghost = pg_strdup(optarg); + dopt.pghost = pg_strdup(optarg); break; case 'i': @@ -425,7 +427,7 @@ main(int argc, char **argv) case 'n': /* include schema(s) */ simple_string_list_append(&schema_include_patterns, optarg); - dopt->include_everything = false; + dopt.include_everything = false; break; case 'N': /* exclude schema(s) */ @@ -433,15 +435,15 @@ main(int argc, char **argv) break; case 'o': /* Dump oids */ - dopt->oids = true; + dopt.oids = true; break; case 'O': /* Don't reconnect to match owner */ - dopt->outputNoOwner = 1; + dopt.outputNoOwner = 1; break; case 'p': /* server port */ - dopt->pgport = pg_strdup(optarg); + dopt.pgport = pg_strdup(optarg); break; case 'R': @@ -449,16 +451,16 @@ main(int argc, char **argv) break; case 's': /* dump schema only */ - dopt->schemaOnly = true; + dopt.schemaOnly = true; break; case 'S': /* Username for superuser in plain text output */ - dopt->outputSuperuser = pg_strdup(optarg); + dopt.outputSuperuser = pg_strdup(optarg); break; case 't': /* include table(s) */ simple_string_list_append(&table_include_patterns, optarg); - dopt->include_everything = false; + dopt.include_everything = false; break; case 'T': /* exclude table(s) */ @@ -466,7 +468,7 @@ main(int argc, char **argv) break; case 'U': - dopt->username = pg_strdup(optarg); + dopt.username = pg_strdup(optarg); break; case 'v': /* verbose */ @@ -482,7 +484,7 @@ main(int argc, char **argv) break; case 'x': /* skip ACL dump */ - dopt->aclsSkip = true; + dopt.aclsSkip = true; break; case 'Z': /* Compression Level */ @@ -494,7 +496,7 @@ main(int argc, char **argv) break; case 2: /* lock-wait-timeout */ - dopt->lockWaitTimeout = pg_strdup(optarg); + dopt.lockWaitTimeout = pg_strdup(optarg); break; case 3: /* SET ROLE */ @@ -506,7 +508,7 @@ main(int argc, char **argv) break; case 5: /* section */ - set_dump_section(optarg, &dopt->dumpSections); + set_dump_section(optarg, &dopt.dumpSections); break; case 6: /* snapshot */ @@ -523,8 +525,8 @@ main(int argc, char **argv) * Non-option argument specifies database name as long as it wasn't * already specified with -d / --dbname */ - if (optind < argc && dopt->dbname == NULL) - dopt->dbname = argv[optind++]; + if (optind < argc && dopt.dbname == NULL) + dopt.dbname = argv[optind++]; /* Complain if any arguments remain */ if (optind < argc) @@ -537,29 +539,29 @@ main(int argc, char **argv) } /* --column-inserts implies --inserts */ - if (dopt->column_inserts) - dopt->dump_inserts = 1; + if (dopt.column_inserts) + dopt.dump_inserts = 1; - if (dopt->dataOnly && dopt->schemaOnly) + if (dopt.dataOnly && dopt.schemaOnly) { write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n"); exit_nicely(1); } - if (dopt->dataOnly && dopt->outputClean) + if (dopt.dataOnly && dopt.outputClean) { write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n"); exit_nicely(1); } - if (dopt->dump_inserts && dopt->oids) + if (dopt.dump_inserts && dopt.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_nicely(1); } - if (dopt->if_exists && !dopt->outputClean) + if (dopt.if_exists && !dopt.outputClean) exit_horribly(NULL, "option --if-exists requires option -c/--clean\n"); /* Identify archive format to emit */ @@ -620,15 +622,15 @@ main(int argc, char **argv) * Open the database using the Archiver, so it knows about it. Errors mean * death. */ - ConnectDatabase(fout, dopt->dbname, dopt->pghost, dopt->pgport, dopt->username, prompt_password); - setup_connection(fout, dopt, dumpencoding, dumpsnapshot, use_role); + ConnectDatabase(fout, dopt.dbname, dopt.pghost, dopt.pgport, dopt.username, prompt_password); + setup_connection(fout, &dopt, dumpencoding, dumpsnapshot, use_role); /* * Disable security label support if server version < v9.1.x (prevents * access to nonexistent pg_seclabel catalog) */ if (fout->remoteVersion < 90100) - dopt->no_security_labels = 1; + dopt.no_security_labels = 1; /* * When running against 9.0 or later, check if we are in recovery mode, @@ -644,7 +646,7 @@ main(int argc, char **argv) * On hot standby slaves, never try to dump unlogged table data, * since it will just throw an error. */ - dopt->no_unlogged_table_data = true; + dopt.no_unlogged_table_data = true; } PQclear(res); } @@ -659,7 +661,7 @@ main(int argc, char **argv) /* check the version for the synchronized snapshots feature */ if (numWorkers > 1 && fout->remoteVersion < 90200 - && !dopt->no_synchronized_snapshots) + && !dopt.no_synchronized_snapshots) exit_horribly(NULL, "Synchronized snapshots are not supported by this server version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" @@ -714,27 +716,27 @@ main(int argc, char **argv) * Dumping blobs is now default unless we saw an inclusion switch or -s * ... but even if we did see one of these, -b turns it back on. */ - if (dopt->include_everything && !dopt->schemaOnly) - dopt->outputBlobs = true; + if (dopt.include_everything && !dopt.schemaOnly) + dopt.outputBlobs = true; /* * Now scan the database and create DumpableObject structs for all the * objects we intend to dump. */ - tblinfo = getSchemaData(fout, dopt, &numTables); + tblinfo = getSchemaData(fout, &dopt, &numTables); if (fout->remoteVersion < 80400) guessConstraintInheritance(tblinfo, numTables); - if (!dopt->schemaOnly) + if (!dopt.schemaOnly) { - getTableData(dopt, tblinfo, numTables, dopt->oids); + getTableData(&dopt, tblinfo, numTables, dopt.oids); buildMatViewRefreshDependencies(fout); - if (dopt->dataOnly) + if (dopt.dataOnly) getTableDataFKConstraints(); } - if (dopt->outputBlobs) + if (dopt.outputBlobs) getBlobs(fout); /* @@ -784,12 +786,12 @@ main(int argc, char **argv) dumpStdStrings(fout); /* The database item is always next, unless we don't want it at all */ - if (dopt->include_everything && !dopt->dataOnly) - dumpDatabase(fout, dopt); + if (dopt.include_everything && !dopt.dataOnly) + dumpDatabase(fout, &dopt); /* Now the rearrangeable objects. */ for (i = 0; i < numObjs; i++) - dumpDumpableObject(fout, dopt, dobjs[i]); + dumpDumpableObject(fout, &dopt, dobjs[i]); /* * Set up options info to ensure we dump what we want. @@ -798,25 +800,25 @@ main(int argc, char **argv) ropt->filename = filename; /* if you change this list, see dumpOptionsFromRestoreOptions */ - ropt->dropSchema = dopt->outputClean; - ropt->dataOnly = dopt->dataOnly; - ropt->schemaOnly = dopt->schemaOnly; - ropt->if_exists = dopt->if_exists; - ropt->column_inserts = dopt->column_inserts; - ropt->dumpSections = dopt->dumpSections; - ropt->aclsSkip = dopt->aclsSkip; - ropt->superuser = dopt->outputSuperuser; - ropt->createDB = dopt->outputCreateDB; - ropt->noOwner = dopt->outputNoOwner; - ropt->noTablespace = dopt->outputNoTablespaces; - ropt->disable_triggers = dopt->disable_triggers; - ropt->use_setsessauth = dopt->use_setsessauth; - ropt->disable_dollar_quoting = dopt->disable_dollar_quoting; - ropt->dump_inserts = dopt->dump_inserts; - ropt->no_security_labels = dopt->no_security_labels; - ropt->lockWaitTimeout = dopt->lockWaitTimeout; - ropt->include_everything = dopt->include_everything; - ropt->enable_row_security = dopt->enable_row_security; + ropt->dropSchema = dopt.outputClean; + ropt->dataOnly = dopt.dataOnly; + ropt->schemaOnly = dopt.schemaOnly; + ropt->if_exists = dopt.if_exists; + ropt->column_inserts = dopt.column_inserts; + ropt->dumpSections = dopt.dumpSections; + ropt->aclsSkip = dopt.aclsSkip; + ropt->superuser = dopt.outputSuperuser; + ropt->createDB = dopt.outputCreateDB; + ropt->noOwner = dopt.outputNoOwner; + ropt->noTablespace = dopt.outputNoTablespaces; + ropt->disable_triggers = dopt.disable_triggers; + ropt->use_setsessauth = dopt.use_setsessauth; + ropt->disable_dollar_quoting = dopt.disable_dollar_quoting; + ropt->dump_inserts = dopt.dump_inserts; + ropt->no_security_labels = dopt.no_security_labels; + ropt->lockWaitTimeout = dopt.lockWaitTimeout; + ropt->include_everything = dopt.include_everything; + ropt->enable_row_security = dopt.enable_row_security; if (compressLevel == -1) ropt->compression = 0; @@ -845,7 +847,7 @@ main(int argc, char **argv) if (plainText) RestoreArchive(fout); - CloseArchive(fout, dopt); + CloseArchive(fout, &dopt); exit_nicely(0); } -- 2.40.0