help-gengetopt
[Top][All Lists]
Advanced

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

Re: [help-gengetopt] make cmd_line_list and cmd_line_list_tmp static?


From: Andre Noll
Subject: Re: [help-gengetopt] make cmd_line_list and cmd_line_list_tmp static?
Date: Thu, 13 Apr 2006 19:03:18 +0200
User-agent: Mutt/1.5.9i

On 11:09, Lorenzo Bettini wrote:
> Andre Noll wrote:
> >On 21:40, Lorenzo Bettini wrote:
> >>actually I haven't found your explanation (Andre) in the info file of 
> >>glibc,
> >
> >to which explanation are you referring here?
> 
> This one:
> 
> The problem is that gengetopt generates code that always sets the
> extern variable "optind" to one before entering the loop which calls
> getopt_long(). According to POSIX, this instructs getopt_long() to
> continue to parse those command line options that were passed to it
> during the previous call.

I think this is implicitly contained in the following from man 3 getopt:

        If  getopt() finds another option character, it returns that
        character, updating the external variable optind and a static
        variable nextchar  so that  the  next  call to getopt()
        can resume the scan with the following option character
        or argv-element.

So using "nextchar" implies "continue to parse those command line
options that were passed to it during the previous call"

I used valgrind and found that my problem indeed is "nextchar" being
a dangling pointer, see below.

> actually optind is the index of the next argument to scan (1 because the 
> 0 is the program name)

Sure, but in glibc's getopt.c the special value zero is used for
initialization (as documented in getopt.c, see my previous mail):

  if (d->optind == 0 || !d->__initialized)
    { 
      if (d->optind == 0)
        d->optind = 1;  /* Don't scan ARGV[0], the program name.  */
      optstring = _getopt_initialize (argc, argv, optstring, d);
      d->__initialized = 1;
    }
  ...
  if (d->__nextchar == NULL || *d->__nextchar == '\0')
                               ^^^^^^^^^^^^^^

The important thing is that _getopt_initialize() sets the dangling
d->__nextchar to NULL. This explains why the marked expression isn't
executed if optind == 0, but accesses memory already freed if optind
!= 0.

Unfortunately, "optind = 0 means initialize" seems to be a glibc
feature that is not backed up by POSIX. So I agree that gengetopt
should not rely on it. Which leaves the question how to tell getopt
to discard any internal pointers in a portable way.

> 
> <SNIP>
> 
> OK, I'll check it!

Thanks. An uptodate tarball (automatically generated each night)
is always available at

        http://www.paraslash.org/versions/paraslash-git.tar.bz2

> >>Notice that, if you use the configuration parser generated by gengetopt, 
> >>this will construct a correct array (by inserting, as the first element, 
> >>the name of the program).
> >
> >I'm not sure I understand this as I don't see where the config parser
> >constructs an array.
> 
> probably because you did not enable the config parser feature in gengetopt?

Yeah, true ;)

But argv[0] really isn't the problem. It is set properly.

Have fun
Andre
-- 
The only person who always got his work done by Friday was Robinson Crusoe

Attachment: signature.asc
Description: Digital signature


reply via email to

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