Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.92) (envelope-from ) id 1jGEaK-0002Ck-G8 for pgsql-bugs@arkaria.postgresql.org; Mon, 23 Mar 2020 04:21:08 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1jGEaG-0002fu-FI for pgsql-bugs@arkaria.postgresql.org; Mon, 23 Mar 2020 04:21:04 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1jGEaG-0002fn-6v for pgsql-bugs@lists.postgresql.org; Mon, 23 Mar 2020 04:21:04 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jGEa9-0003xR-BH for pgsql-bugs@lists.postgresql.org; Mon, 23 Mar 2020 04:21:03 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id 02N4Kp2Q018356; Mon, 23 Mar 2020 00:20:52 -0400 From: Tom Lane To: Bruce Momjian cc: jim_gray@cox.net, pgsql-bugs@lists.postgresql.org Subject: Re: BUG #16304: ECPG won't accept input from STDIN In-reply-to: <20200323024509.GD2031@momjian.us> References: <16304-c662b00a1322db7f@postgresql.org> <20200323024509.GD2031@momjian.us> Comments: In-reply-to Bruce Momjian message dated "Sun, 22 Mar 2020 22:45:09 -0400" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <18207.1584936980.0@sss.pgh.pa.us> Date: Mon, 23 Mar 2020 00:20:51 -0400 Message-ID: <18355.1584937251@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <18207.1584936980.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Bruce Momjian writes: > On Mon, Mar 16, 2020 at 08:48:22PM +0000, PG Bug reporting form wrote: >> On an older version (9.6.3) of Postgres on CentOS 7.7.1908, ECPG accept= s >> input from STDIN: >> ... >> On a newer version (11.5) of Postgres on AIX 7.2, ECPG does NOT accept = input >> from STDIN: >> I suspect a problem in the Postgres version of getopt_long.c > Yeah, you might be right. In some cases we use the libc (maybe GNU) > getopt-long, and in other cases we use our own version, and there are > behavioral differences between the two. The fact you are testing on > CentOS and the other on AIX probably explains it. I think using > /dev/stdin should work on both. Oooh! I'd looked at this report and figured that somebody broke ecpg's command parsing, not thinking hard about the platform dependence angle. But you are both right: our version of getopt_long() fails to treat bare "-" correctly. It starts parsing it as options, fails to find '\0' in the options string, and returns BADCH. This is (a) useless; there's no possible value in that behavior (b) unlike what GNU getopt_long does (c) clearly not what ecpg is expecting. Although it's not documented (also our bad), a look at ecpg.c clearly shows that it intends to treat bare "-" as a filename argument meaning stdin (d) arguably wrong according to POSIX. POSIX doesn't specify getopt_long of course, but it does specify getopt(), and that page is absolutely unambiguous that an argv element containing just "-" is to be treated as a non-switch argument. (Which indeed our version of getopt does) So I think we ought to fix it, as attached. I've verified that on a platform using our getopt_long, ecpg misbehaves as reported, and this fixes it. We should also fix ecpg's documentation... regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="fix-getopt-long-for-bare-dash.patch"; charset="us-ascii" Content-ID: <18207.1584936980.2@sss.pgh.pa.us> Content-Description: fix-getopt-long-for-bare-dash.patch diff --git a/src/port/getopt_long.c b/src/port/getopt_long.c index ff379db..c989276 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; ------- =_aaaaaaaaaa0--