summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-03-23 11:58:01 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-03-23 11:58:01 -0400
commitc0eb57dd989b7f4c2faf486a39c83dd8a4ae4189 (patch)
tree567e446e7d5fbc1b0d93623a4b2bc4d13da51e2f /src
parentce5ed3806ec69a304be208d86047cc4008a1ab8f (diff)
Fix our getopt_long's behavior for a command line argument of just "-".
src/port/getopt_long.c failed on such an argument, always seeing it as an unrecognized switch. This is unhelpful; better is to treat such an item as a non-switch argument. That behavior is what we find in GNU's getopt_long(); it's what src/port/getopt.c does; and it is required by POSIX for getopt(), which getopt_long() ought to be generally a superset of. Moreover, it's expected by ecpg, which intends an argument of "-" to mean "read from stdin". So fix it. Also add some documentation about ecpg's behavior in this area, since that was miserably underdocumented. I had to reverse-engineer it from the code. Per bug #16304 from James Gray. Back-patch to all supported branches, since this has been broken forever. Discussion: https://postgr.es/m/16304-c662b00a1322db7f@postgresql.org
Diffstat (limited to 'src')
-rw-r--r--src/port/getopt_long.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/port/getopt_long.c b/src/port/getopt_long.c
index aa5b7319fd5..d5e61aed7af 100644
--- a/src/port/getopt_long.c
+++ b/src/port/getopt_long.c
@@ -79,14 +79,22 @@ getopt_long(int argc, char *const argv[],
place++;
- if (place[0] && place[0] == '-' && place[1] == '\0')
- { /* found "--" */
+ if (!*place)
+ {
+ /* treat "-" as not being an option */
+ place = EMSG;
+ return -1;
+ }
+
+ if (place[0] == '-' && place[1] == '\0')
+ {
+ /* found "--", treat it as end of options */
++optind;
place = EMSG;
return -1;
}
- if (place[0] && place[0] == '-' && place[1])
+ if (place[0] == '-' && place[1])
{
/* long option */
size_t namelen;