Fabien COELHO <coe...@cri.ensmp.fr> writes:
> There seems to be other instances as well

Thanks! I made the same modification of src/interfaces/ecpg/preproc/ecpg.c, but
in other cases it's either not a problem (as with src/bin/psql/startup.c or
src/timezone/zic.c) or the solution is too complex to be added to the current
patch: e.g. these tools in src/bin/scripts use handle_help_version_opts function
from src/bin/scripts/common.c which cannot be refactored so straightforward.
It's possible to remove it and modify each tool to parse the --help and
--version args for themselves but I would not include it in the same patch as
it's already not too short for a "fix" patch and these changes are better to be
discussed separately IMHO. Do you think the handle_help_version_opts function
should be removed and these args should be parsed in each src/bin/scripts app?

There are several cases where separate comparisons of argv[1] are made to detect
"--help" or "--version" before non-root user is enforced (to make it possible to
the root user to check the version) e.g. src/bin/pg_upgrade/option.c — in this
case I left this comparisons untouched while expanding the switch statement of
getopt_long, so non-root user sees the correct behavior and root still sees
"cannot be run as root" error when trying # pg_upgrade -v --help. The
alternative is to wrap these argv[...] comparisons in a for statement to
iterate through all the arguments. Another option is to enforce non-root after
getopt_long parsing but it's harder to be sure that the patch does not alter
the apps behavior unexpected way.

There are also the few apps when getopt is used instead of getopt_long, so I
decided not to fix these in the current patch because it's not so obvious. It's
possible either to replace getopt with getopt_long (and add long options, which
may be nice) or wrap --help/--version parsing in a for loop.

--
Andrei
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 3f203c6ca6..7a23c0b1ab 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -3130,23 +3130,9 @@ main(int argc, char *argv[])
 	progname = get_progname(argv[0]);
 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb"));
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			usage(progname);
-			exit(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("initdb (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
 	/* process command-line options */
 
-	while ((c = getopt_long(argc, argv, "dD:E:kL:nNU:WA:sST:X:g", long_options, &option_index)) != -1)
+	while ((c = getopt_long(argc, argv, "dD:E:kL:nNU:WA:sST:X:gV?", long_options, &option_index)) != -1)
 	{
 		switch (c)
 		{
@@ -3243,6 +3229,14 @@ main(int argc, char *argv[])
 			case 'g':
 				SetDataDirectoryCreatePerm(PG_DIR_MODE_GROUP);
 				break;
+			case 'V':
+				puts("initdb (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
+			case '?':
+				usage(progname);
+				exit(0);
+				break;
 			default:
 				/* getopt_long already emitted a complaint */
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index ef4cfc4384..03f7875514 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -2169,24 +2169,9 @@ main(int argc, char **argv)
 	progname = get_progname(argv[0]);
 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			usage();
-			exit(0);
-		}
-		else if (strcmp(argv[1], "-V") == 0
-				 || strcmp(argv[1], "--version") == 0)
-		{
-			puts("pg_basebackup (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
 	atexit(cleanup_directories_atexit);
 
-	while ((c = getopt_long(argc, argv, "CD:F:r:RS:T:X:l:nNzZ:d:c:h:p:U:s:wWkvP",
+	while ((c = getopt_long(argc, argv, "CD:F:r:RS:T:X:l:nNzZ:d:c:h:p:U:s:wWkvPV?",
 							long_options, &option_index)) != -1)
 	{
 		switch (c)
@@ -2328,6 +2313,14 @@ main(int argc, char **argv)
 			case 'P':
 				showprogress = true;
 				break;
+			case 'V':
+				puts("pg_basebackup (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
+			case '?':
+				usage();
+				exit(0);
+				break;
 			case 3:
 				verify_checksums = false;
 				break;
diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c
index 8be8d48a8a..5318454d67 100644
--- a/src/bin/pg_basebackup/pg_receivewal.c
+++ b/src/bin/pg_basebackup/pg_receivewal.c
@@ -509,22 +509,7 @@ main(int argc, char **argv)
 	progname = get_progname(argv[0]);
 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			usage();
-			exit(0);
-		}
-		else if (strcmp(argv[1], "-V") == 0 ||
-				 strcmp(argv[1], "--version") == 0)
-		{
-			puts("pg_receivewal (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
-	while ((c = getopt_long(argc, argv, "D:d:E:h:p:U:s:S:nwWvZ:",
+	while ((c = getopt_long(argc, argv, "D:d:E:h:p:U:s:S:nwWvVZ:?",
 							long_options, &option_index)) != -1)
 	{
 		switch (c)
@@ -584,6 +569,10 @@ main(int argc, char **argv)
 			case 'v':
 				verbose++;
 				break;
+			case 'V':
+				puts("pg_receivewal (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
 			case 'Z':
 				compresslevel = atoi(optarg);
 				if (compresslevel < 0 || compresslevel > 9)
@@ -593,6 +582,10 @@ main(int argc, char **argv)
 					exit(1);
 				}
 				break;
+			case '?':
+				usage();
+				exit(0);
+				break;
 /* action */
 			case 1:
 				do_create_slot = true;
diff --git a/src/bin/pg_basebackup/pg_recvlogical.c b/src/bin/pg_basebackup/pg_recvlogical.c
index ef85c9af4c..170e7475eb 100644
--- a/src/bin/pg_basebackup/pg_recvlogical.c
+++ b/src/bin/pg_basebackup/pg_recvlogical.c
@@ -711,22 +711,7 @@ main(int argc, char **argv)
 	progname = get_progname(argv[0]);
 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			usage();
-			exit(0);
-		}
-		else if (strcmp(argv[1], "-V") == 0 ||
-				 strcmp(argv[1], "--version") == 0)
-		{
-			puts("pg_recvlogical (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
-	while ((c = getopt_long(argc, argv, "E:f:F:nvd:h:p:U:wWI:o:P:s:S:",
+	while ((c = getopt_long(argc, argv, "E:f:F:nvd:h:p:U:wWI:o:P:s:S:V?",
 							long_options, &option_index)) != -1)
 	{
 		switch (c)
@@ -750,6 +735,14 @@ main(int argc, char **argv)
 			case 'v':
 				verbose++;
 				break;
+			case 'V':
+				puts("pg_recvlogical (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
+			case '?':
+				usage();
+				exit(0);
+				break;
 /* connection options */
 			case 'd':
 				dbname = pg_strdup(optarg);
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 895a51f89d..9c8ba27764 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -88,6 +88,8 @@ main(int argc, char *argv[])
 {
 	static struct option long_options[] = {
 		{"pgdata", required_argument, NULL, 'D'},
+		{"version", no_argument, NULL, 'V'},
+		{"help", no_argument, NULL, '?'},
 		{NULL, 0, NULL, 0}
 	};
 
@@ -110,21 +112,7 @@ main(int argc, char *argv[])
 
 	progname = get_progname(argv[0]);
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			usage(progname);
-			exit(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("pg_controldata (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
-	while ((c = getopt_long(argc, argv, "D:", long_options, NULL)) != -1)
+	while ((c = getopt_long(argc, argv, "D:V?", long_options, NULL)) != -1)
 	{
 		switch (c)
 		{
@@ -132,6 +120,16 @@ main(int argc, char *argv[])
 				DataDir = optarg;
 				break;
 
+			case 'V':
+				puts("pg_controldata (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
+
+			case '?':
+				usage(progname);
+				exit(0);
+				break;
+
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 				exit(1);
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index ed2396aa6c..8779cb6a66 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -2220,7 +2220,7 @@ main(int argc, char **argv)
 	/* process command-line options */
 	while (optind < argc)
 	{
-		while ((c = getopt_long(argc, argv, "cD:e:l:m:N:o:p:P:sS:t:U:wW",
+		while ((c = getopt_long(argc, argv, "cD:e:l:m:N:o:p:P:sS:t:U:VwW?",
 								long_options, &option_index)) != -1)
 		{
 			switch (c)
@@ -2296,12 +2296,20 @@ main(int argc, char **argv)
 						/* Prepend .\ for local accounts */
 						register_username = psprintf(".\\%s", optarg);
 					break;
+				case 'V':
+					puts("pg_ctl (PostgreSQL) " PG_VERSION);
+					exit(0);
+					break;
 				case 'w':
 					do_wait = true;
 					break;
 				case 'W':
 					do_wait = false;
 					break;
+				case '?':
+					do_help();
+					exit(0);
+					break;
 				case 'c':
 					allow_core_files = true;
 					break;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 86524d6598..0f961bf9a6 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -399,23 +399,9 @@ main(int argc, char **argv)
 
 	progname = get_progname(argv[0]);
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			help(progname);
-			exit_nicely(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("pg_dump (PostgreSQL) " PG_VERSION);
-			exit_nicely(0);
-		}
-	}
-
 	InitDumpOptions(&dopt);
 
-	while ((c = getopt_long(argc, argv, "abBcCd:E:f:F:h:j:n:N:oOp:RsS:t:T:U:vwWxZ:",
+	while ((c = getopt_long(argc, argv, "abBcCd:E:f:F:h:j:n:N:oOp:RsS:t:T:U:vVwWxZ:?",
 							long_options, &optindex)) != -1)
 	{
 		switch (c)
@@ -514,6 +500,11 @@ main(int argc, char **argv)
 				g_verbose = true;
 				break;
 
+			case 'V':			/* version */
+				puts("pg_dump (PostgreSQL) " PG_VERSION);
+				exit_nicely(0);
+				break;
+
 			case 'w':
 				prompt_password = TRI_NO;
 				break;
@@ -535,6 +526,11 @@ main(int argc, char **argv)
 				}
 				break;
 
+			case '?':			/* help */
+				help(progname);
+				exit_nicely(0);
+				break;
+
 			case 0:
 				/* This covers the long options. */
 				break;
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index eb29d318a4..7312a8c7ce 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -110,10 +110,12 @@ main(int argc, char *argv[])
 		{"tablespaces-only", no_argument, NULL, 't'},
 		{"username", required_argument, NULL, 'U'},
 		{"verbose", no_argument, NULL, 'v'},
+		{"version", no_argument, NULL, 'V'},
 		{"no-password", no_argument, NULL, 'w'},
 		{"password", no_argument, NULL, 'W'},
 		{"no-privileges", no_argument, NULL, 'x'},
 		{"no-acl", no_argument, NULL, 'x'},
+		{"help", no_argument, NULL, '?'},
 
 		/*
 		 * the following options don't have an equivalent short option letter
@@ -165,20 +167,6 @@ main(int argc, char *argv[])
 
 	progname = get_progname(argv[0]);
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			help();
-			exit_nicely(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("pg_dumpall (PostgreSQL) " PG_VERSION);
-			exit_nicely(0);
-		}
-	}
-
 	if ((ret = find_other_exec(argv[0], "pg_dump", PGDUMP_VERSIONSTR,
 							   pg_dump_bin)) < 0)
 	{
@@ -205,7 +193,7 @@ main(int argc, char *argv[])
 
 	pgdumpopts = createPQExpBuffer();
 
-	while ((c = getopt_long(argc, argv, "acd:E:f:gh:l:oOp:rsS:tU:vwWx", long_options, &optindex)) != -1)
+	while ((c = getopt_long(argc, argv, "acd:E:f:gh:l:oOp:rsS:tU:vVwWx?", long_options, &optindex)) != -1)
 	{
 		switch (c)
 		{
@@ -284,6 +272,11 @@ main(int argc, char *argv[])
 				appendPQExpBufferStr(pgdumpopts, " -v");
 				break;
 
+			case 'V':
+				puts("pg_dumpall (PostgreSQL) " PG_VERSION);
+				exit_nicely(0);
+				break;
+
 			case 'w':
 				prompt_password = TRI_NO;
 				appendPQExpBufferStr(pgdumpopts, " -w");
@@ -299,6 +292,11 @@ main(int argc, char *argv[])
 				appendPQExpBufferStr(pgdumpopts, " -x");
 				break;
 
+			case '?':
+				help();
+				exit_nicely(0);
+				break;
+
 			case 0:
 				break;
 
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index 501d7cea72..5735608b1b 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -106,7 +106,9 @@ main(int argc, char **argv)
 		{"use-list", 1, NULL, 'L'},
 		{"username", 1, NULL, 'U'},
 		{"verbose", 0, NULL, 'v'},
+		{"version", 0, NULL, 'V'},
 		{"single-transaction", 0, NULL, '1'},
+		{"help", 0, NULL, '?'},
 
 		/*
 		 * the following options don't have an equivalent short option letter
@@ -136,21 +138,7 @@ main(int argc, char **argv)
 
 	progname = get_progname(argv[0]);
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			usage(progname);
-			exit_nicely(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("pg_restore (PostgreSQL) " PG_VERSION);
-			exit_nicely(0);
-		}
-	}
-
-	while ((c = getopt_long(argc, argv, "acCd:ef:F:h:I:j:lL:n:N:Op:P:RsS:t:T:U:vwWx1",
+	while ((c = getopt_long(argc, argv, "acCd:ef:F:h:I:j:lL:n:N:Op:P:RsS:t:T:U:vVwWx1?",
 							cmdopts, NULL)) != -1)
 	{
 		switch (c)
@@ -249,6 +237,11 @@ main(int argc, char **argv)
 				opts->verbose = 1;
 				break;
 
+			case 'V':			/* version */
+				puts("pg_restore (PostgreSQL) " PG_VERSION);
+				exit_nicely(0);
+				break;
+
 			case 'w':
 				opts->promptPassword = TRI_NO;
 				break;
@@ -266,6 +259,11 @@ main(int argc, char **argv)
 				opts->exit_on_error = true;
 				break;
 
+			case '?':			/* help */
+				usage(progname);
+				exit_nicely(0);
+				break;
+
 			case 0:
 
 				/*
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index d63a3a27f6..05114a2133 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -101,7 +101,9 @@ main(int argc, char *argv[])
 		{"dry-run", no_argument, NULL, 'n'},
 		{"next-oid", required_argument, NULL, 'o'},
 		{"multixact-offset", required_argument, NULL, 'O'},
+		{"version", no_argument, NULL, 'V'},
 		{"next-transaction-id", required_argument, NULL, 'x'},
+		{"help", no_argument, NULL, '?'},
 		{"wal-segsize", required_argument, NULL, 1},
 		{NULL, 0, NULL, 0}
 	};
@@ -120,22 +122,7 @@ main(int argc, char *argv[])
 
 	progname = get_progname(argv[0]);
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			usage();
-			exit(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("pg_resetwal (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
-
-	while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:x:", long_options, NULL)) != -1)
+	while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:Vx:?", long_options, NULL)) != -1)
 	{
 		switch (c)
 		{
@@ -293,6 +280,16 @@ main(int argc, char *argv[])
 				log_fname = pg_strdup(optarg);
 				break;
 
+			case 'V':
+				puts("pg_resetwal (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
+
+			case '?':
+				usage();
+				exit(0);
+				break;
+
 			case 1:
 				set_wal_segsize = strtol(optarg, &endptr, 10) * 1024 * 1024;
 				if (endptr == optarg || *endptr != '\0')
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c
index 9653106386..ad181d5b2c 100644
--- a/src/bin/pg_rewind/pg_rewind.c
+++ b/src/bin/pg_rewind/pg_rewind.c
@@ -115,27 +115,19 @@ main(int argc, char **argv)
 	progname = get_progname(argv[0]);
 
 	/* Process command-line arguments */
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			usage(progname);
-			exit(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("pg_rewind (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
-	while ((c = getopt_long(argc, argv, "D:nNP", long_options, &option_index)) != -1)
+	while ((c = getopt_long(argc, argv, "D:nNPV?", long_options, &option_index)) != -1)
 	{
 		switch (c)
 		{
 			case '?':
-				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
-				exit(1);
+				usage(progname);
+				exit(0);
+				break;
+
+			case 'V':
+				puts("pg_rewind (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
 
 			case 'P':
 				showprogress = true;
diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index e6f7ef8557..50e8ad50ce 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -141,27 +141,15 @@ handle_args(int argc, char *argv[])
 	static struct option long_options[] = {
 		{"filename", required_argument, NULL, 'f'},
 		{"secs-per-test", required_argument, NULL, 's'},
+		{"version", no_argument, NULL, 'V'},
+		{"help", no_argument, NULL, '?'},
 		{NULL, 0, NULL, 0}
 	};
 
 	int			option;			/* Command line option */
 	int			optindex = 0;	/* used by getopt_long */
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			printf(_("Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n"), progname);
-			exit(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("pg_test_fsync (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
-	while ((option = getopt_long(argc, argv, "f:s:",
+	while ((option = getopt_long(argc, argv, "f:s:V?",
 								 long_options, &optindex)) != -1)
 	{
 		switch (option)
@@ -174,6 +162,16 @@ handle_args(int argc, char *argv[])
 				secs_per_test = atoi(optarg);
 				break;
 
+			case 'V':
+				puts("pg_test_fsync (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
+
+			case '?':
+				printf(_("Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n"), progname);
+				exit(0);
+				break;
+
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
 						progname);
diff --git a/src/bin/pg_test_timing/pg_test_timing.c b/src/bin/pg_test_timing/pg_test_timing.c
index 6e2fd1ab8c..4e24e8a599 100644
--- a/src/bin/pg_test_timing/pg_test_timing.c
+++ b/src/bin/pg_test_timing/pg_test_timing.c
@@ -42,27 +42,15 @@ handle_args(int argc, char *argv[])
 {
 	static struct option long_options[] = {
 		{"duration", required_argument, NULL, 'd'},
+		{"version", no_argument, NULL, 'V'},
+		{"help", no_argument, NULL, '?'},
 		{NULL, 0, NULL, 0}
 	};
 
 	int			option;			/* Command line option */
 	int			optindex = 0;	/* used by getopt_long */
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			printf(_("Usage: %s [-d DURATION]\n"), progname);
-			exit(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("pg_test_timing (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
-	while ((option = getopt_long(argc, argv, "d:",
+	while ((option = getopt_long(argc, argv, "d:V?",
 								 long_options, &optindex)) != -1)
 	{
 		switch (option)
@@ -71,6 +59,16 @@ handle_args(int argc, char *argv[])
 				test_duration = atoi(optarg);
 				break;
 
+			case 'V':
+				puts("pg_test_timing (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
+
+			case '?':
+				printf(_("Usage: %s [-d DURATION]\n"), progname);
+				exit(0);
+				break;
+
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
 						progname);
diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c
index 9dbc9225a6..30a6831e2a 100644
--- a/src/bin/pg_upgrade/option.c
+++ b/src/bin/pg_upgrade/option.c
@@ -53,6 +53,8 @@ parseCommandLine(int argc, char *argv[])
 		{"retain", no_argument, NULL, 'r'},
 		{"jobs", required_argument, NULL, 'j'},
 		{"verbose", no_argument, NULL, 'v'},
+		{"version", no_argument, NULL, 'V'},
+		{"help", no_argument, NULL, '?'},
 		{NULL, 0, NULL, 0}
 	};
 	int			option;			/* Command line option */
@@ -100,7 +102,7 @@ parseCommandLine(int argc, char *argv[])
 	if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL)
 		pg_fatal("could not write to log file \"%s\"\n", INTERNAL_LOG_FILE);
 
-	while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:v",
+	while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:vV?",
 								 long_options, &optindex)) != -1)
 	{
 		switch (option)
@@ -203,6 +205,16 @@ parseCommandLine(int argc, char *argv[])
 				log_opts.verbose = true;
 				break;
 
+			case 'V':
+				puts("pg_upgrade (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
+
+			case '?':
+				usage();
+				exit(0);
+				break;
+
 			default:
 				pg_fatal("Try \"%s --help\" for more information.\n",
 						 os_info.progname);
diff --git a/src/bin/pg_verify_checksums/pg_verify_checksums.c b/src/bin/pg_verify_checksums/pg_verify_checksums.c
index 28c975446e..ca45cc126e 100644
--- a/src/bin/pg_verify_checksums/pg_verify_checksums.c
+++ b/src/bin/pg_verify_checksums/pg_verify_checksums.c
@@ -208,6 +208,8 @@ main(int argc, char *argv[])
 {
 	static struct option long_options[] = {
 		{"pgdata", required_argument, NULL, 'D'},
+		{"help", no_argument, NULL, '?'},
+		{"version", no_argument, NULL, 'V'},
 		{NULL, 0, NULL, 0}
 	};
 
@@ -220,21 +222,7 @@ main(int argc, char *argv[])
 
 	progname = get_progname(argv[0]);
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			usage();
-			exit(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("pg_verify_checksums (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
-	while ((c = getopt_long(argc, argv, "D:r:d", long_options, &option_index)) != -1)
+	while ((c = getopt_long(argc, argv, "dD:r:V?", long_options, &option_index)) != -1)
 	{
 		switch (c)
 		{
@@ -252,6 +240,14 @@ main(int argc, char *argv[])
 				}
 				only_relfilenode = pstrdup(optarg);
 				break;
+			case 'V':
+				puts("pg_verify_checksums (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
+			case '?':
+				usage();
+				exit(0);
+				break;
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 				exit(1);
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 41b756c089..d1ff85a677 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -4763,6 +4763,7 @@ main(int argc, char **argv)
 		{"define", required_argument, NULL, 'D'},
 		{"file", required_argument, NULL, 'f'},
 		{"fillfactor", required_argument, NULL, 'F'},
+		{"help", no_argument, NULL, '?'},
 		{"host", required_argument, NULL, 'h'},
 		{"initialize", no_argument, NULL, 'i'},
 		{"init-steps", required_argument, NULL, 'I'},
@@ -4783,6 +4784,7 @@ main(int argc, char **argv)
 		{"transactions", required_argument, NULL, 't'},
 		{"username", required_argument, NULL, 'U'},
 		{"vacuum-all", no_argument, NULL, 'v'},
+		{"version", no_argument, NULL, 'V'},
 		/* long-named only options */
 		{"unlogged-tables", no_argument, NULL, 1},
 		{"tablespace", required_argument, NULL, 2},
@@ -4832,20 +4834,6 @@ main(int argc, char **argv)
 
 	progname = get_progname(argv[0]);
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			usage();
-			exit(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			puts("pgbench (PostgreSQL) " PG_VERSION);
-			exit(0);
-		}
-	}
-
 #ifdef WIN32
 	/* stderr is buffered on Win32. */
 	setvbuf(stderr, NULL, _IONBF, 0);
@@ -4868,7 +4856,7 @@ main(int argc, char **argv)
 		exit(1);
 	}
 
-	while ((c = getopt_long(argc, argv, "iI:h:nvp:dqb:SNc:j:Crs:t:T:U:lf:D:F:M:P:R:L:", long_options, &optindex)) != -1)
+	while ((c = getopt_long(argc, argv, "iI:h:nvp:dqb:SNc:j:Crs:t:T:U:lf:D:F:M:P:R:L:V?", long_options, &optindex)) != -1)
 	{
 		char	   *script;
 
@@ -5097,6 +5085,14 @@ main(int argc, char **argv)
 					latency_limit = (int64) (limit_ms * 1000);
 				}
 				break;
+			case 'V':
+				puts("pgbench (PostgreSQL) " PG_VERSION);
+				exit(0);
+				break;
+			case '?':
+				usage();
+				exit(0);
+				break;
 			case 1:				/* unlogged-tables */
 				initialization_option_set = true;
 				unlogged_tables = true;
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index 9a94e39545..a91df891bf 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -116,6 +116,8 @@ int
 main(int argc, char *const argv[])
 {
 	static struct option ecpg_options[] = {
+		{"version", no_argument, NULL, 'V'},
+		{"help", no_argument, NULL, '?'},
 		{"regression", no_argument, NULL, ECPG_GETOPT_LONG_REGRESSION},
 		{NULL, 0, NULL, 0}
 	};
@@ -140,22 +142,8 @@ main(int argc, char *const argv[])
 		return ILLEGAL_OPTION;
 	}
 
-	if (argc > 1)
-	{
-		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
-		{
-			help(progname);
-			exit(0);
-		}
-		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
-		{
-			printf("ecpg %s\n", PG_VERSION);
-			exit(0);
-		}
-	}
-
 	output_filename = NULL;
-	while ((c = getopt_long(argc, argv, "vcio:I:tD:dC:r:h", ecpg_options, NULL)) != -1)
+	while ((c = getopt_long(argc, argv, "vcio:I:tD:dC:r:hV?", ecpg_options, NULL)) != -1)
 	{
 		switch (c)
 		{
@@ -242,6 +230,14 @@ main(int argc, char *const argv[])
 						progname);
 #endif
 				break;
+			case 'V':
+				printf("ecpg %s\n", PG_VERSION);
+				exit(0);
+				break;
+			case '?':
+				help(progname);
+				exit(0);
+				break;
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), argv[0]);
 				return ILLEGAL_OPTION;

Reply via email to