[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-block] [PATCH v2] qemu-io: Reinitialize optind to 1 (not 0) be

From: Max Reitz
Subject: Re: [Qemu-block] [PATCH v2] qemu-io: Reinitialize optind to 1 (not 0) before parsing inner command.
Date: Mon, 7 Jan 2019 19:14:09 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1

On 07.01.19 18:59, Eric Blake wrote:
> On 1/7/19 11:50 AM, Max Reitz wrote:
>>>>> Note I didn't set optreset.  It's not present in glibc and the "hard
>>>>> reset" is not necessary in this context.
>>>> But it sure sounds like FreeBSD requires you to set it, doesn't it?
> No.  Quoting https://www.freebsd.org/cgi/man.cgi?getopt(3)
>      The variables opterr and optind are both initialized to 1.        The 
> optind
>      variable may be set to another value before a set of calls       to
> getopt() in
>      order to skip over       more or less argv entries.
> so resetting it to 1 as a soft reset is no different to setting it to 2
> to skip argv[1].

In theory it is very much different because the text clearly says "in
order to skip", not "in order to re-parse or use a different argv".
Especially the fact that we use different argvs is something that
implementations may not expect.

> It just means that you didn't get the hard reset of
> internal state (there is definitely internal state if argv[1] was merged
> short options - but that state is cleared if you run getopt() until it
> returns -1;

While I agree that this is probably the case in practice, I see no
reason why this should be the case if it isn't guaranteed.  Why should
the state be cleared once you reach the end?

> there may also be internal state if you used extensions, but
> when you don't use extensions, such internal state is irrelevant).
> I think the BSD man page needs updating, and that will probably happen
> if I file my promised POSIX defect.

Sure.  But as it is, it doesn't tell me that resetting optind to 1 is
sufficient to be able to parse a new argv.
>>> At the end of the day, both GNU optind=0 and BSD optreset=1 are
>>> sufficient to force a hard reset of all hidden state.  But if you don't
>>> use POSIX extensions, and always run getopt() until a -1 return, then
>>> setting optind=1 is a portable soft reset, regardless of how the hidden
>>> state is implemented, and regardless of how (or even if) libc offers a
>>> hard reset, even though POSIX itself is currently lacking that mention.
>>> (I should probably file a POSIX defect to get that wording listed in POSIX)
>> Hm, OK?  Is there any guarantee for that behavior for FreeBSD, or is
>> that just how it is?  Because the man page is very clear on it:
>> "optreset must be set to 1".  It doesn't talk about soft or hard resets
>> like the glibc man page does.
>> And if optreset not being available for glibc is the only issue, I'd say
>> adding it as a weak global variable would work without #ifdefs.
> I don't see the point - Richard has already tested that optind = 1
> worked on BSD machines for our purposes, so we don't have to worry about
> the hard reset aspect of optreset=1.

Well, and as far as I remember glibc's memcpy() at one point only copied
in one direction and things broke badly once they reversed it at some
point for some CPUs.

Just because it works now doesn't mean it will work always if the
specification allows for different behavior.

> (But yes, it would also be nice if
> BSD and glibc folks could agree on how to do hard resets, instead of
> having two different incompatible ways)
I don't see why we should have a general code path if there is no
standard way of resetting getopt() other than "This seems to work".
What's so bad about a weak optreset or an
"#ifdef __FreeBSD__; optreset = 1; #endif"?

Sure, if you can get POSIX to define the fact that optind = 1 after
getopt() == -1 will be sufficient to start parsing a new argv, that'd be
great.  But there is no such standard yet (other than "Why would that
not work?").


Attachment: signature.asc
Description: OpenPGP digital signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]