Email List: Xaustin-review-lX
[All Lists]

Re: Defect in XSH getopt

To: Geoff Clare <gwc@xxxxxxxxxxxxx>
Subject: Re: Defect in XSH getopt
From: Michael Kerrisk <mtk.lists@xxxxxxxxx>
Date: Fri, 11 Jul 2008 21:44:28 +0200
Cc: austin-review-l@xxxxxxxxxxxxx
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:cc:subject:references:in-reply-to :content-type:content-transfer-encoding; bh=BfrSbfE5gBO5vkpLQ6hKaaweAL76WcC5eSIgF1O9g50=; b=rYy85nIvrIBOmIJKw0x8aHWPyxXIAgTfu8crbh8fazzxCfWobgM2pBb2LVL6YzYbE9 iuwzRcFX3lYvnCXZ8uOnhBCCigHp4bdGIPdfz8DA1OfrkCLmQcg9xlj7oTbcqsnJSVqI zmmGp9KTZLJ/Jg8PYwwy50rLiP5elSOriFJ6M=
Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; b=BIpYSciRs1flm5wXq2OrcCWMBda1T1Gc+m5SFnzCwwYKKDwLPEg6Tp8J1E/u2oNRjE y300nvFqVGTQDtu2wLplC+YvO5oEUDDas4XJzNyn6VIsdRRuOjq5JAQb00kD0RCXUNwh ypYorLQP3cxUgglJwlxCKSEy6E2bQIvSbqa78=
References: <20080711144003.GA30947@xxxxxx>
Geoff Clare wrote:
@ page 541 line 17820 section getopt objection [gwc optind zero]

Problem:

Defect code :  3. Clarification required

The description of getopt() does not give any significance to a
value of zero for optind.  It just says "The variable optind is the
index of the next element of the argv[] vector to be processed. It
shall be initialized to 1 by the system, and getopt() shall update it
when it finishes with each element of argv[]."

Based on this, an application writer might expect that if they
have an argument vector consisting just of options and operands
(i.e. no utility name or equivalent in argv[0]), then they should
be able to use getopt() to process this vector from the beginning
by setting optind to zero before the first call.

However, in practice this is not portable because some
implementations treat an optind value of zero in a special way.
(According to Michael Kerrisk, for the glibc getopt() an optind of
zero causes a reinitialisation of extended features.  Resetting it
to 1 in order to scan a new vector only works if extensions are not
used.  BSD apparently treats an optind of zero as a reset for
compatibility with glibc.)
Some more details here:
http://groups.google.com/group/comp.unix.programmer/browse_thread/thread/be0d0b7a07a165fb

Some relevant pieces from the Linux getopt(3) man page (some parts are from the still-to-be-released next version, which has changes based on my current understanding of what glibc's getopt() does):

[...]
DESCRIPTION
[...]

The variable optind is the index of the next element to be pro-
cessed in argv. The system initializes this value to 1. The
caller can reset it to 1 to restart scanning of the same argv,
or when scanning a new argument vector.

[...]

By default, getopt() permutes the contents of argv as it scans,
so that eventually all the non-options are at the end. Two
other modes are also implemented. If the first character of
optstring is '+' or the environment variable POSIXLY_CORRECT is
set, then option processing stops as soon as a non-option argu-
ment is encountered. If the first character of optstring is
'-', then each non-option argv-element is handled as if it were
the argument of an option with character code 1. (This is used
by programs that were written to expect options and other argv-
elements in any order and that care about the ordering of the
two.) The special argument "--" forces an end of option-scan-
ning regardless of the scanning mode.

[...]

CONFORMING TO
getopt():
POSIX.2 and POSIX.1-2001, provided the environment vari-
able POSIXLY_CORRECT is set. Otherwise, the elements of
argv aren't really const, because we permute them. We
pretend they're const in the prototype to be compatible
with other systems.

The use of '+' and '-' in optstring is a GNU extension.

[...]

NOTES
A program that scans multiple argument vectors, or rescans the
same vector more than once, and wants to make use of GNU exten-
sions such as '+' and -' at the start of optstring, or changes
the value of POSIXLY_CORRECT between scans, must reinitialize
getopt() by resetting optind to 0, rather than the traditional
value of 1. (Resetting to 0 forces the invocation of an inter-
nal initialization routine that rechecks POSIXLY_CORRECT and
checks for GNU extensions in optstring.)

Cheers,

Michael


Either the POSIX description should be updated to say that if
optind is zero the behaviour is unspecified, or the rationale should
be updated to say that treating an optind of zero as special is not
conforming.  The action below does the former.

Action:

On line 17820 after "and getopt() shall update it when it finishes
with each element of argv[]", add a new sentence:

    "If the application sets optind to zero before calling getopt(),
    the behavior is unspecified."







<Prev in Thread] Current Thread [Next in Thread>