#include "common/link-canary.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
-#include "pg_getopt.h"
+#include "port/pg_getopt_ctx.h"
#include "postmaster/postmaster.h"
#include "storage/bufpage.h"
#include "storage/fd.h"
{
int i;
char *progname = argv[0];
+ pg_getopt_ctx optctx;
int flag;
char *userDoption = NULL;
uint32 bootstrap_data_checksum_version = 0; /* No checksum */
argv++;
argc--;
- while ((flag = getopt(argc, argv, "B:c:d:D:Fkr:X:-:")) != -1)
+ pg_getopt_start(&optctx, argc, argv, "B:c:d:D:Fkr:X:-:");
+ while ((flag = pg_getopt_next(&optctx)) != -1)
{
switch (flag)
{
case 'B':
- SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV);
+ SetConfigOption("shared_buffers", optctx.optarg, PGC_POSTMASTER, PGC_S_ARGV);
break;
case '-':
* returns DISPATCH_POSTMASTER if it doesn't find a match, so
* error for anything else.
*/
- if (parse_dispatch_option(optarg) != DISPATCH_POSTMASTER)
+ if (parse_dispatch_option(optctx.optarg) != DISPATCH_POSTMASTER)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("--%s must be first argument", optarg)));
+ errmsg("--%s must be first argument", optctx.optarg)));
pg_fallthrough;
case 'c':
char *name,
*value;
- ParseLongOption(optarg, &name, &value);
+ ParseLongOption(optctx.optarg, &name, &value);
if (!value)
{
if (flag == '-')
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("--%s requires a value",
- optarg)));
+ optctx.optarg)));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("-c %s requires a value",
- optarg)));
+ optctx.optarg)));
}
SetConfigOption(name, value, PGC_POSTMASTER, PGC_S_ARGV);
break;
}
case 'D':
- userDoption = pstrdup(optarg);
+ userDoption = pstrdup(optctx.optarg);
break;
case 'd':
{
/* Turn on debugging for the bootstrap process. */
char *debugstr;
- debugstr = psprintf("debug%s", optarg);
+ debugstr = psprintf("debug%s", optctx.optarg);
SetConfigOption("log_min_messages", debugstr,
PGC_POSTMASTER, PGC_S_ARGV);
SetConfigOption("client_min_messages", debugstr,
bootstrap_data_checksum_version = PG_DATA_CHECKSUM_VERSION;
break;
case 'r':
- strlcpy(OutputFileName, optarg, MAXPGPATH);
+ strlcpy(OutputFileName, optctx.optarg, MAXPGPATH);
break;
case 'X':
- SetConfigOption("wal_segment_size", optarg, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
+ SetConfigOption("wal_segment_size", optctx.optarg, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
break;
default:
write_stderr("Try \"%s --help\" for more information.\n",
}
}
- if (argc != optind)
+ if (argc != optctx.optind)
{
write_stderr("%s: invalid command-line arguments\n", progname);
proc_exit(1);
#include "lib/ilist.h"
#include "libpq/libpq.h"
#include "libpq/pqsignal.h"
-#include "pg_getopt.h"
#include "pgstat.h"
#include "port/pg_bswap.h"
+#include "port/pg_getopt_ctx.h"
#include "postmaster/autovacuum.h"
#include "postmaster/bgworker_internals.h"
#include "postmaster/pgarch.h"
void
PostmasterMain(int argc, char *argv[])
{
+ pg_getopt_ctx optctx;
int opt;
int status;
char *userDoption = NULL;
*/
InitializeGUCOptions();
- opterr = 1;
-
/*
* Parse command-line options. CAUTION: keep this in sync with
* tcop/postgres.c (the option sets should not conflict) and with the
* common help() function in main/main.c.
*/
- while ((opt = getopt(argc, argv, "B:bC:c:D:d:EeFf:h:ijk:lN:OPp:r:S:sTt:W:-:")) != -1)
+ pg_getopt_start(&optctx, argc, argv, "B:bC:c:D:d:EeFf:h:ijk:lN:OPp:r:S:sTt:W:-:");
+ optctx.opterr = 1;
+ while ((opt = pg_getopt_next(&optctx)) != -1)
{
switch (opt)
{
case 'B':
- SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV);
+ SetConfigOption("shared_buffers", optctx.optarg, PGC_POSTMASTER, PGC_S_ARGV);
break;
case 'b':
break;
case 'C':
- output_config_variable = strdup(optarg);
+ output_config_variable = strdup(optctx.optarg);
break;
case '-':
* returns DISPATCH_POSTMASTER if it doesn't find a match, so
* error for anything else.
*/
- if (parse_dispatch_option(optarg) != DISPATCH_POSTMASTER)
+ if (parse_dispatch_option(optctx.optarg) != DISPATCH_POSTMASTER)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("--%s must be first argument", optarg)));
+ errmsg("--%s must be first argument", optctx.optarg)));
pg_fallthrough;
case 'c':
char *name,
*value;
- ParseLongOption(optarg, &name, &value);
+ ParseLongOption(optctx.optarg, &name, &value);
if (!value)
{
if (opt == '-')
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("--%s requires a value",
- optarg)));
+ optctx.optarg)));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("-c %s requires a value",
- optarg)));
+ optctx.optarg)));
}
SetConfigOption(name, value, PGC_POSTMASTER, PGC_S_ARGV);
}
case 'D':
- userDoption = strdup(optarg);
+ userDoption = strdup(optctx.optarg);
break;
case 'd':
- set_debug_options(atoi(optarg), PGC_POSTMASTER, PGC_S_ARGV);
+ set_debug_options(atoi(optctx.optarg), PGC_POSTMASTER, PGC_S_ARGV);
break;
case 'E':
break;
case 'f':
- if (!set_plan_disabling_options(optarg, PGC_POSTMASTER, PGC_S_ARGV))
+ if (!set_plan_disabling_options(optctx.optarg, PGC_POSTMASTER, PGC_S_ARGV))
{
write_stderr("%s: invalid argument for option -f: \"%s\"\n",
- progname, optarg);
+ progname, optctx.optarg);
ExitPostmaster(1);
}
break;
case 'h':
- SetConfigOption("listen_addresses", optarg, PGC_POSTMASTER, PGC_S_ARGV);
+ SetConfigOption("listen_addresses", optctx.optarg, PGC_POSTMASTER, PGC_S_ARGV);
break;
case 'i':
break;
case 'k':
- SetConfigOption("unix_socket_directories", optarg, PGC_POSTMASTER, PGC_S_ARGV);
+ SetConfigOption("unix_socket_directories", optctx.optarg, PGC_POSTMASTER, PGC_S_ARGV);
break;
case 'l':
break;
case 'N':
- SetConfigOption("max_connections", optarg, PGC_POSTMASTER, PGC_S_ARGV);
+ SetConfigOption("max_connections", optctx.optarg, PGC_POSTMASTER, PGC_S_ARGV);
break;
case 'O':
break;
case 'p':
- SetConfigOption("port", optarg, PGC_POSTMASTER, PGC_S_ARGV);
+ SetConfigOption("port", optctx.optarg, PGC_POSTMASTER, PGC_S_ARGV);
break;
case 'r':
break;
case 'S':
- SetConfigOption("work_mem", optarg, PGC_POSTMASTER, PGC_S_ARGV);
+ SetConfigOption("work_mem", optctx.optarg, PGC_POSTMASTER, PGC_S_ARGV);
break;
case 's':
case 't':
{
- const char *tmp = get_stats_option_name(optarg);
+ const char *tmp = get_stats_option_name(optctx.optarg);
if (tmp)
{
else
{
write_stderr("%s: invalid argument for option -t: \"%s\"\n",
- progname, optarg);
+ progname, optctx.optarg);
ExitPostmaster(1);
}
break;
}
case 'W':
- SetConfigOption("post_auth_delay", optarg, PGC_POSTMASTER, PGC_S_ARGV);
+ SetConfigOption("post_auth_delay", optctx.optarg, PGC_POSTMASTER, PGC_S_ARGV);
break;
default:
/*
* Postmaster accepts no non-option switch arguments.
*/
- if (optind < argc)
+ if (optctx.optind < argc)
{
write_stderr("%s: invalid argument: \"%s\"\n",
- progname, argv[optind]);
+ progname, argv[optctx.optind]);
write_stderr("Try \"%s --help\" for more information.\n",
progname);
ExitPostmaster(1);
ExitPostmaster(1);
}
- /*
- * Now that we are done processing the postmaster arguments, reset
- * getopt(3) library so that it will work correctly in subprocesses.
- */
- optind = 1;
-#ifdef HAVE_INT_OPTRESET
- optreset = 1; /* some systems need this too */
-#endif
-
/* For debugging: display postmaster environment */
if (message_level_is_interesting(DEBUG3))
{
#include "optimizer/optimizer.h"
#include "parser/analyze.h"
#include "parser/parser.h"
-#include "pg_getopt.h"
#include "pg_trace.h"
#include "pgstat.h"
+#include "port/pg_getopt_ctx.h"
#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
#include "replication/logicallauncher.h"
int errs = 0;
GucSource gucsource;
int flag;
+ pg_getopt_ctx optctx;
if (secure)
{
gucsource = PGC_S_CLIENT; /* switches came from client */
}
-#ifdef HAVE_INT_OPTERR
+ /*
+ * Parse command-line options. CAUTION: keep this in sync with
+ * postmaster/postmaster.c (the option sets should not conflict) and with
+ * the common help() function in main/main.c.
+ */
+ pg_getopt_start(&optctx, argc, argv, "B:bC:c:D:d:EeFf:h:ijk:lN:nOPp:r:S:sTt:v:W:-:");
/*
* Turn this off because it's either printed to stderr and not the log
* where we'd want it, or argv[0] is now "--single", which would make for
* a weird error message. We print our own error message below.
*/
- opterr = 0;
-#endif
+ optctx.opterr = 0;
- /*
- * Parse command-line options. CAUTION: keep this in sync with
- * postmaster/postmaster.c (the option sets should not conflict) and with
- * the common help() function in main/main.c.
- */
- while ((flag = getopt(argc, argv, "B:bC:c:D:d:EeFf:h:ijk:lN:nOPp:r:S:sTt:v:W:-:")) != -1)
+ while ((flag = pg_getopt_next(&optctx)) != -1)
{
switch (flag)
{
case 'B':
- SetConfigOption("shared_buffers", optarg, ctx, gucsource);
+ SetConfigOption("shared_buffers", optctx.optarg, ctx, gucsource);
break;
case 'b':
* returns DISPATCH_POSTMASTER if it doesn't find a match, so
* error for anything else.
*/
- if (parse_dispatch_option(optarg) != DISPATCH_POSTMASTER)
+ if (parse_dispatch_option(optctx.optarg) != DISPATCH_POSTMASTER)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("--%s must be first argument", optarg)));
+ errmsg("--%s must be first argument", optctx.optarg)));
pg_fallthrough;
case 'c':
char *name,
*value;
- ParseLongOption(optarg, &name, &value);
+ ParseLongOption(optctx.optarg, &name, &value);
if (!value)
{
if (flag == '-')
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("--%s requires a value",
- optarg)));
+ optctx.optarg)));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("-c %s requires a value",
- optarg)));
+ optctx.optarg)));
}
SetConfigOption(name, value, ctx, gucsource);
pfree(name);
case 'D':
if (secure)
- userDoption = strdup(optarg);
+ userDoption = strdup(optctx.optarg);
break;
case 'd':
- set_debug_options(atoi(optarg), ctx, gucsource);
+ set_debug_options(atoi(optctx.optarg), ctx, gucsource);
break;
case 'E':
break;
case 'f':
- if (!set_plan_disabling_options(optarg, ctx, gucsource))
+ if (!set_plan_disabling_options(optctx.optarg, ctx, gucsource))
errs++;
break;
case 'h':
- SetConfigOption("listen_addresses", optarg, ctx, gucsource);
+ SetConfigOption("listen_addresses", optctx.optarg, ctx, gucsource);
break;
case 'i':
break;
case 'k':
- SetConfigOption("unix_socket_directories", optarg, ctx, gucsource);
+ SetConfigOption("unix_socket_directories", optctx.optarg, ctx, gucsource);
break;
case 'l':
break;
case 'N':
- SetConfigOption("max_connections", optarg, ctx, gucsource);
+ SetConfigOption("max_connections", optctx.optarg, ctx, gucsource);
break;
case 'n':
break;
case 'p':
- SetConfigOption("port", optarg, ctx, gucsource);
+ SetConfigOption("port", optctx.optarg, ctx, gucsource);
break;
case 'r':
/* send output (stdout and stderr) to the given file */
if (secure)
- strlcpy(OutputFileName, optarg, MAXPGPATH);
+ strlcpy(OutputFileName, optctx.optarg, MAXPGPATH);
break;
case 'S':
- SetConfigOption("work_mem", optarg, ctx, gucsource);
+ SetConfigOption("work_mem", optctx.optarg, ctx, gucsource);
break;
case 's':
case 't':
{
- const char *tmp = get_stats_option_name(optarg);
+ const char *tmp = get_stats_option_name(optctx.optarg);
if (tmp)
SetConfigOption(tmp, "true", ctx, gucsource);
* standalone backend.
*/
if (secure)
- FrontendProtocol = (ProtocolVersion) atoi(optarg);
+ FrontendProtocol = (ProtocolVersion) atoi(optctx.optarg);
break;
case 'W':
- SetConfigOption("post_auth_delay", optarg, ctx, gucsource);
+ SetConfigOption("post_auth_delay", optctx.optarg, ctx, gucsource);
break;
default:
/*
* Optional database name should be there only if *dbname is NULL.
*/
- if (!errs && dbname && *dbname == NULL && argc - optind >= 1)
- *dbname = strdup(argv[optind++]);
+ if (!errs && dbname && *dbname == NULL && argc - optctx.optind >= 1)
+ *dbname = strdup(argv[optctx.optind++]);
- if (errs || argc != optind)
+ if (errs || argc != optctx.optind)
{
if (errs)
- optind--; /* complain about the previous argument */
+ optctx.optind--; /* complain about the previous argument */
/* spell the error message a bit differently depending on context */
if (IsUnderPostmaster)
ereport(FATAL,
errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("invalid command-line argument for server process: %s", argv[optind]),
+ errmsg("invalid command-line argument for server process: %s", argv[optctx.optind]),
errhint("Try \"%s --help\" for more information.", progname));
else
ereport(FATAL,
errcode(ERRCODE_SYNTAX_ERROR),
errmsg("%s: invalid command-line argument: %s",
- progname, argv[optind]),
+ progname, argv[optctx.optind]),
errhint("Try \"%s --help\" for more information.", progname));
}
-
- /*
- * Reset getopt(3) library so that it will work correctly in subprocesses
- * or when this function is called a second time with another array.
- */
- optind = 1;
-#ifdef HAVE_INT_OPTRESET
- optreset = 1; /* some systems need this too */
-#endif
}
* into the argv array, and will get horribly confused when it is
* re-called to analyze a subprocess' argument string if the argv storage
* has been clobbered meanwhile. Other platforms have other dependencies
- * on argv[].
+ * on argv[]. (We use custom pg_getopt_start/next() functions nowadays
+ * that don't do that, but those other dependencies might still exist.)
*/
{
char **new_argv;