mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Fix option argument lookup in in-tree getopt_long().
The in-tree getopt_long() moves each non-option to the end of argv,
which might put it right where an option's argument lookup expects
to find the argument. For example, "vacuumdb postgres --jobs"
takes "postgres" as the number of jobs instead of complaining that
--jobs is missing its argument. To fix, stop the argument lookups
at the start of the moved non-options, which we already track to
know when to stop scanning.
Oversight in commit 411b720343.
Author: Sehrope Sarkuni <sehrope@jackdb.com>
Reviewed-by: solai v <solai.cdac@gmail.com>
Discussion: https://postgr.es/m/CAH7T-arxDuVCSkorO%3Dk7%2BM-_JV0JFzMpN_EtKMyD2K0RDqZ2OA%40mail.gmail.com
Backpatch-through: 17
This commit is contained in:
@@ -207,5 +207,9 @@ $node->command_fails_like(
|
||||
[ 'vacuumdb', '-a', 'postgres' ],
|
||||
qr/cannot vacuum all databases and a specific one at the same time/,
|
||||
'cannot use option -a and a dbname as argument at the same time');
|
||||
$node->command_fails_like(
|
||||
[ 'vacuumdb', 'postgres', '--jobs' ],
|
||||
qr/requires an argument/,
|
||||
'option missing its argument after a non-option');
|
||||
|
||||
done_testing();
|
||||
|
||||
@@ -66,6 +66,9 @@ getopt_long(int argc, char *const argv[],
|
||||
static int nonopt_start = -1;
|
||||
static bool force_nonopt = false;
|
||||
|
||||
if (nonopt_start == -1)
|
||||
nonopt_start = argc;
|
||||
|
||||
if (!*place)
|
||||
{ /* update scanning pointer */
|
||||
char **args = (char **) argv;
|
||||
@@ -75,7 +78,7 @@ retry:
|
||||
/*
|
||||
* If we are out of arguments or only non-options remain, return -1.
|
||||
*/
|
||||
if (optind >= argc || optind == nonopt_start)
|
||||
if (optind >= nonopt_start)
|
||||
{
|
||||
place = EMSG;
|
||||
nonopt_start = -1;
|
||||
@@ -99,10 +102,7 @@ retry:
|
||||
args[i] = args[i + 1];
|
||||
args[argc - 1] = place;
|
||||
|
||||
if (nonopt_start == -1)
|
||||
nonopt_start = argc - 1;
|
||||
else
|
||||
nonopt_start--;
|
||||
nonopt_start--;
|
||||
|
||||
goto retry;
|
||||
}
|
||||
@@ -137,7 +137,7 @@ retry:
|
||||
{
|
||||
if (place[namelen] == '=')
|
||||
optarg = place + namelen + 1;
|
||||
else if (optind < argc - 1 &&
|
||||
else if (optind < nonopt_start - 1 &&
|
||||
has_arg == required_argument)
|
||||
{
|
||||
optind++;
|
||||
@@ -220,7 +220,7 @@ retry:
|
||||
{ /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
optarg = place;
|
||||
else if (argc <= ++optind)
|
||||
else if (nonopt_start <= ++optind)
|
||||
{ /* no arg */
|
||||
place = EMSG;
|
||||
if (*optstring == ':')
|
||||
|
||||
Reference in New Issue
Block a user