agora inbox for pgsql-hackers@postgresql.org
help / color / mirror / Atom feedFrom: Nathan Bossart <nathan@postgresql.org>
Subject: [PATCH v2 2/2] Fix option argument lookup in in-tree getopt_long().
Date: Fri, 4 Sep 2026 16:47:53 -0500
The in-tree getopt_long() moves each non-option to the end of argv
as soon as it finds one, which puts a non-option that preceded an
option right where the option's argument lookup expects to find it.
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>
Discussion: https://postgr.es/m/CAH7T-arxDuVCSkorO%3Dk7%2BM-_JV0JFzMpN_EtKMyD2K0RDqZ2OA%40mail.gmail.com
Backpatch-through: 17
---
src/bin/scripts/t/100_vacuumdb.pl | 4 ++++
src/port/getopt_long.c | 14 +++++++-------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/bin/scripts/t/100_vacuumdb.pl b/src/bin/scripts/t/100_vacuumdb.pl
index 7c4e35a6717..b78fa2a38de 100644
--- a/src/bin/scripts/t/100_vacuumdb.pl
+++ b/src/bin/scripts/t/100_vacuumdb.pl
@@ -240,6 +240,10 @@ $node->command_fails_like(
[ 'vacuumdb', '--all', 'postgres' ],
qr/cannot vacuum all databases and a specific one at the same time/,
'cannot use option --all 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');
$node->safe_psql(
'postgres', q|
diff --git a/src/port/getopt_long.c b/src/port/getopt_long.c
index 0a9a50189f1..f2edadb59d5 100644
--- a/src/port/getopt_long.c
+++ b/src/port/getopt_long.c
@@ -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;
}
@@ -139,7 +139,7 @@ retry:
optarg = place + namelen + 1;
else if (has_arg == optional_argument)
optarg = NULL;
- else if (optind < argc - 1)
+ else if (optind < nonopt_start - 1)
{
optind++;
optarg = argv[optind];
@@ -222,7 +222,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 == ':')
--
2.55.0
--Zv9Xg0nwk4TTIGFg--
view thread (180+ messages) latest in thread
Message-ID: <no-message-id-1739224@localhost>
Permalink: ../no-message-id-1739224@localhost/
Also on: postgresql.org/message-id/no-message-id-1739224@localhost
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: nathan@postgresql.org
Subject: Re: [PATCH v2 2/2] Fix option argument lookup in in-tree getopt_long().
In-Reply-To: <no-message-id-1739224@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox