diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2020-03-23 11:58:00 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2020-03-23 11:58:00 -0400 |
commit | 980a70b9763e330dab6d0eb994c96a007876e40e (patch) | |
tree | 0ac3c0b304aef20c27a28647d195e37db5368200 /src | |
parent | c81bd3b9a5e99315148f4f5714c32e633af30123 (diff) | |
download | postgresql-980a70b9763e330dab6d0eb994c96a007876e40e.tar.gz postgresql-980a70b9763e330dab6d0eb994c96a007876e40e.zip |
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.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/port/getopt_long.c b/src/port/getopt_long.c index ff379db29b0..c9892769883 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; |