From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/11855 Path: news.gmane.org!.POSTED!not-for-mail From: Denys Vlasenko Newsgroups: gmane.linux.lib.musl.general Subject: Re: getopt() not exposing __optpos - shell needs it Date: Tue, 29 Aug 2017 13:32:01 +0200 Message-ID: References: <20170828152844.GY1627@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" X-Trace: blaine.gmane.org 1504006356 24611 195.159.176.226 (29 Aug 2017 11:32:36 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 29 Aug 2017 11:32:36 +0000 (UTC) To: musl , Rich Felker Original-X-From: musl-return-11868-gllmg-musl=m.gmane.org@lists.openwall.com Tue Aug 29 13:32:29 2017 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1dmeku-000619-Kz for gllmg-musl@m.gmane.org; Tue, 29 Aug 2017 13:32:28 +0200 Original-Received: (qmail 24296 invoked by uid 550); 29 Aug 2017 11:32:33 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 24278 invoked from network); 29 Aug 2017 11:32:33 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=iZht3vq6/YDfQEzRTL7lebGtnE/uKyqQSOoZFmv5rcE=; b=uAh83tBmgv0Eko3iPil+QOmyMUN+EJvIcmdZNJAXU8GktSsTCzMwfoflcvzhpDDDn5 vhH8DxDb7dhU6e/Ly896Kbsb9HBdHBGJLPi/FxPuARQbP+8FUZrf+hACkiThGcvAo8zp l9dCMQrAxdaD7pB09d3WzM1q9XM2fmx7PznRx2bEKntRq1W2Ht/B7ekSIdMl8rzmJahd rYakkuQ/b02NQm1qgW/A669UmEld8r+LcGP9MgxFwMxTru0LShn2RAitzq4SBxHKMFX+ TbWT6h6wD5BDbGXKYq0gU5hwRwn4YJkEiZHQJ+5+UK56sWvqDvbJ3L0zm66A7b8s8yer Tk1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=iZht3vq6/YDfQEzRTL7lebGtnE/uKyqQSOoZFmv5rcE=; b=hXSw5NmtV9Q1SJfF+zXutuEqUbnVhzG225+V9abYUjykH2w5lG1oJdWugo9mBZ7GEE C1pZtRciAcduVKDYNFxpGPP2Iy532WEh+86dA/Cp/wMezayWvJfk23xlBFEYULl5GPde 1D6OBc0sihKdl7bfLKXk3Zg7aw4NCPTmArerKEyIgbBFlBHWaHIXqaLt+RLkyshk71w8 bE06T59+QrRZd47jvQtCXJI/Jg7Rt8plLbGes1P6F3Un2EqxlAwJnNtF0j4kjciLi5hs Z5ygf+NKL2evYKCbOLj6Ydn6yH6f6lUEE7hpPDzaJksTFO1XkFK1wBXQL+/XeH4u9r6X J51A== X-Gm-Message-State: AHYfb5jfT/83tpVdOpCMRtm8hvlbyHSVZaJ9WmUYWDp52tPQiWgXGcYu qM4dote5AlLNHo+5FuYzjNUfOKWQNxoH X-Received: by 10.80.184.117 with SMTP id k50mr3188720ede.293.1504006341607; Tue, 29 Aug 2017 04:32:21 -0700 (PDT) In-Reply-To: <20170828152844.GY1627@brightrain.aerifal.cx> Xref: news.gmane.org gmane.linux.lib.musl.general:11855 Archived-At: On Mon, Aug 28, 2017 at 5:28 PM, Rich Felker wrote: > On Mon, Aug 28, 2017 at 12:18:57PM +0200, Denys Vlasenko wrote: >> I am using getopt() in busybox hush shell. >> "unset" builtin, for example: it takes -v and -f options. >> This works fine. >> >> However, POSIX requires that shells has a "getopts" builtin: >> http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html >> >> It is basically an API binding to access getopt() in the shell code: >> it uses OPTIND and (in bash) OPTERR on entry, returns a single-char >> variable on return and updates OPTIND and OPTARG. Sounds familiar, right? >> >> When I try to do that (use getopt() to implement "getopts"), it hits a snag. >> Unlike normal getopt() usage in C programs, where it is called in a loop >> with the same argv[] array until parsing is finished, >> when it is used from "getopts", each successive call will (usually) have >> the same argv[] CONTENTS, but not the ADDRESSES. >> (The reason is in how shell works: it re-creates command arguments just before >> running a command, since there can be variable substitution, globbing, etc). > > First, some background out of the spec to establish what is supposed > to work and what's not: > > If the application sets OPTIND to the value 1, a new set of > parameters can be used: either the current positional parameters > or new arg values. Any other attempt to invoke getopts multiple > times in a single shell execution environment with parameters > (positional parameters or arg operands) that are not the same in > all invocations, or with an OPTIND value modified to be a value > other than 1, produces unspecified results. > > What this means is that, when you use getopts(1), you need to either > use the exact same arguments (as you said, *string contents*, not > likely to be the same argv[] pointers) or reset it with OPTIND=1. > > It seems to me that the easiest, fully-portable fix is just the > obvious quadratic-time solution: on each run of getopts(1), reset > getopt(3) to the start and call it ++N times. This has several problems: It prints multiple messages "invalid option -q" when there are options which are not in optstring. It mangles optarg if an option without argument follows an option with an argument.