Thread: why was the VAR 'optind' never changed in initdb?

why was the VAR 'optind' never changed in initdb?

From
Clover White
Date:
Hi,<br />  I'm debugging initdb using gdb.<br />  I found that I could not step in the function getopt_long in line
2572in initdb.c.<br />  I also found that the value of VAR optind never be changed. VAR optind is always equal to 1 but
howcould optind be larger than the value of argc(the value of argc is 6) in line 2648 and 2654.<br /><br />I was so
confused.Could someone give me some help? Thank you~<br /><br />here is my configure:<br />./configure CFLAGS=-O0
--enable-debug--enable-depend --enable-cassert --prefix=/home/pgsql/pgsql<br /><br />follows is my debug log by gdb:<br
/><br/>[pgsql@vmlinux postgresql-9.1.2]$ gdb initdb<br />GNU gdb Red Hat Linux (6.3.0.0-1.63rh)<br />Copyright 2004
FreeSoftware Foundation, Inc.<br />GDB is free software, covered by the GNU General Public License, and you are<br />
welcometo change it and/or distribute copies of it under certain conditions.<br />Type "show copying" to see the
conditions.<br/>There is absolutely no warranty for GDB.  Type "show warranty" for details.<br /> This GDB was
configuredas "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".<br /><br />(gdb)
setargs -U pgsql -W -D /home/pgsql/pg_data<br />(gdb) b main<br />Breakpoint 1 at 0x804d133: file initdb.c, line
2553.<br/> (gdb) b 2572<br />Breakpoint 2 at 0x804d20c: file initdb.c, line 2572.<br />(gdb) run<br />Starting program:
/home/pgsql/pgsql/bin/initdb-U pgsql -W -D /home/pgsql/pg_data<br /><br />Breakpoint 1, main (argc=6, argv=0xbfec0ad4)
atinitdb.c:2553<br /> 2553            progname = get_progname(argv[0]);<br />(gdb) c<br />Continuing.<br /><br
/>Breakpoint2, main (argc=6, argv=0xbfec0ad4) at initdb.c:2572<br />2572            while ((c = getopt_long(argc, argv,
"dD:E:L:nU:WA:sT:X:",long_options, &option_index)) != -1)<br /> (gdb) p optind<br />$1 = 1<br />(gdb) s<br
/>2574                   switch (c)<br />(gdb) n<br />2589                                    username =
xstrdup(optarg);<br/>(gdb) <br />2590                                    break;<br />(gdb) p optind<br /> $2 = 1<br
/>(gdb)n<br /><br />Breakpoint 2, main (argc=6, argv=0xbfec0ad4) at initdb.c:2572<br />2572            while ((c =
getopt_long(argc,argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index)) != -1)<br />(gdb) p optind<br /> $3 =
1<br/>(gdb) n<br />2574                    switch (c)<br />(gdb) p optind<br />$4 = 1<br />(gdb) n<br
/>2586                                   pwprompt = true;<br />(gdb) <br />2587                                   
break;<br/>(gdb) <br /><br />Breakpoint 2, main (argc=6, argv=0xbfec0ad4) at initdb.c:2572<br />2572            while
((c= getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index)) != -1)<br />(gdb) p optind<br />$5
=1<br /> (gdb) n<br />2574                    switch (c)<br />(gdb) <br />2580                                   
pg_data= xstrdup(optarg);<br />(gdb) p optarg<br />$6 = 0x0<br />(gdb) n<br />2581                                   
break;<br/> (gdb) p optarg<br /> $7 = 0x0<br />(gdb) n<br /><br />Breakpoint 2, main (argc=6, argv=0xbfec0ad4) at
initdb.c:2572<br/>2572            while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options,
&option_index))!= -1)<br /> (gdb) p pg_data<br /> $8 = 0x9d328e8 "/home/pgsql/pg_data"<br />(gdb) n<br
/>2648           if (optind < argc)<br />(gdb) p optind<br />$9 = 1<br />(gdb) p argc<br />$10 = 6<br />(gdb) n<br
/>2654           if (optind < argc)<br />(gdb) p optind<br /> $11 = 1<br />(gdb) p argc<br />$12 = 6<br />(gdb) n<br
/>2663           if (pwprompt && pwfilename)<br />(gdb) <br clear="all" /><br />-- <br />Clover White<br /><br
/>

Re: why was the VAR 'optind' never changed in initdb?

From
Andrew Dunstan
Date:

On 04/09/2012 07:38 AM, Clover White wrote:
> Hi,
>   I'm debugging initdb using gdb.
>   I found that I could not step in the function getopt_long in line 
> 2572 in initdb.c.
>   I also found that the value of VAR optind never be changed. VAR 
> optind is always equal to 1 but how could optind be larger than the 
> value of argc(the value of argc is 6) in line 2648 and 2654.
>
> I was so confused. Could someone give me some help? Thank you~
>
>

Why do you expect it to be? Perhaps if you tell us what problem you're 
actually trying to solve we can help you better.

cheers

andrew


Re: why was the VAR 'optind' never changed in initdb?

From
Robert Haas
Date:
On Mon, Apr 9, 2012 at 7:38 AM, Clover White <mywhiteclover@gmail.com> wrote:
> Hi,
>   I'm debugging initdb using gdb.
>   I found that I could not step in the function getopt_long in line 2572 in
> initdb.c.
>   I also found that the value of VAR optind never be changed. VAR optind is
> always equal to 1 but how could optind be larger than the value of argc(the
> value of argc is 6) in line 2648 and 2654.

Read the man page for getopt_long.  It changes the global variable optind.

It's a silly interface, but also a long and hallowed UNIX tradition,
so we're stuck with it.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Re: why was the VAR 'optind' never changed in initdb?

From
Clover White
Date:
<div class="gmail_quote">2012/4/9 Andrew Dunstan <span dir="ltr"><<a
href="mailto:andrew@dunslane.net">andrew@dunslane.net</a>></span><br/><blockquote class="gmail_quote"
style="margin:00 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br /><br /> On 04/09/2012 07:38
AM,Clover White wrote:<br /><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc
solid;padding-left:1ex">Hi,<br />  I'm debugging initdb using gdb.<br />  I found that I could not step in the function
getopt_longin line 2572 in initdb.c.<br />  I also found that the value of VAR optind never be changed. VAR optind is
alwaysequal to 1 but how could optind be larger than the value of argc(the value of argc is 6) in line 2648 and
2654.<br/><br /> I was so confused. Could someone give me some help? Thank you~<br /><br /><br /></blockquote><br
/></div>Why do you expect it to be? Perhaps if you tell us what problem you're actually trying to solve we can help you
better.<br/><br /> cheers<br /><font color="#888888"><br /> andrew<br /></font></blockquote></div><br />Hi, this is my
story,it may be a little long :)<br />  I mistook the parameter -W of initdb at the first time and used it like
this:<br/>    initdb -U pgsql -W 12345 -D /home/pgsql/pg_data<br />   And I found the database was not created in the
rightdirectory, but I could not find a log file to find out why.<br />  So, I debug initdb and found out I have mistook
theparameter -W, I should use it like this:<br />    initdb -U pgsql -W -D /home/pgsql/pg_data<br />     <br /> 
however,when I debug initdb.c, VAR optind was supported to increased after getopt_long pasered every parameter,<br /> 
butit was alway equal to 1.<br />  <br />  And there is a segment of initdb.c.<br />    if (optind < argc)<br />    
 {<br />          do something statement<br />      }  <br />  <br />  I print the value of optind and argc:<div
class="im"><br/>    (gdb) p optind<br />    $11 = 1<br />    (gdb) p argc<br />    $12 = 6<br />  <br /></div>  optind
isobvious less than argc, but the statement above do not excute at all.<br />   <br />  QUESTION:<br />    1.why does
thestatement above not excute?<br />    2.why is optind always equal to 1? <br clear="all" /><br />-- <br />Clover
White<br/><br /> 

Re: why was the VAR 'optind' never changed in initdb?

From
Clover White
Date:
<div class="gmail_quote">2012/4/9 Robert Haas <span dir="ltr"><<a
href="mailto:robertmhaas@gmail.com">robertmhaas@gmail.com</a>></span><br/><blockquote class="gmail_quote"
style="margin:00 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Mon, Apr 9, 2012 at 7:38 AM,
CloverWhite <<a href="mailto:mywhiteclover@gmail.com">mywhiteclover@gmail.com</a>> wrote:<br /> > Hi,<br />
>  I'm debugging initdb using gdb.<br /> >   I found that I could not step in the function getopt_long in line
2572in<br /> > initdb.c.<br /> >   I also found that the value of VAR optind never be changed. VAR optind is<br
/>> always equal to 1 but how could optind be larger than the value of argc(the<br /> > value of argc is 6) in
line2648 and 2654.<br /><br /></div>Read the man page for getopt_long.  It changes the global variable optind.<br /><br
/>It's a silly interface, but also a long and hallowed UNIX tradition,<br /> so we're stuck with it.<br /><font
color="#888888"><br/> --<br /> Robert Haas<br /> EnterpriseDB: <a href="http://www.enterprisedb.com"
target="_blank">http://www.enterprisedb.com</a><br/> The Enterprise PostgreSQL Company<br
/></font></blockquote></div><br/>Thanks Robert. I have read the man page for getopt_long and optind. they are in the
sameman page.<br /><br />but i still could not understand why optind always equal to 1 when I gdb initdb and print
optind?<br/> Was optind  supported to increased after getopt_long pasered every parameter?<br clear="all" /><br />--
<br/>Clover White<br /><br /> 

Re: why was the VAR 'optind' never changed in initdb?

From
Andrew Dunstan
Date:

On 04/09/2012 12:36 PM, Clover White wrote:
> 2012/4/9 Andrew Dunstan <andrew@dunslane.net <mailto:andrew@dunslane.net>>
>
>
>
>     On 04/09/2012 07:38 AM, Clover White wrote:
>
>         Hi,
>          I'm debugging initdb using gdb.
>          I found that I could not step in the function getopt_long in
>         line 2572 in initdb.c.
>          I also found that the value of VAR optind never be changed.
>         VAR optind is always equal to 1 but how could optind be larger
>         than the value of argc(the value of argc is 6) in line 2648
>         and 2654.
>
>         I was so confused. Could someone give me some help? Thank you~
>
>
>
>     Why do you expect it to be? Perhaps if you tell us what problem
>     you're actually trying to solve we can help you better.
>
>     cheers
>
>     andrew
>
>
> Hi, this is my story, it may be a little long :)
>   I mistook the parameter -W of initdb at the first time and used it 
> like this:
>     initdb -U pgsql -W 12345 -D /home/pgsql/pg_data
>   And I found the database was not created in the right directory, but 
> I could not find a log file to find out why.
>   So, I debug initdb and found out I have mistook the parameter -W, I 
> should use it like this:
>     initdb -U pgsql -W -D /home/pgsql/pg_data


This is arguably a bug. Maybe we should change this:
     if (optind < argc)     {         pg_data = xstrdup(argv[optind]);         optind++;     }

to
     if (optind < argc && strlen(pg_data) == 0)     {         pg_data = xstrdup(argv[optind]);         optind++;     }

i.e. we'd forbid:
    initdb -D foo bar


which the OP's error more or less devolves to.


cheers

andrew


Re: why was the VAR 'optind' never changed in initdb?

From
Tom Lane
Date:
Andrew Dunstan <andrew@dunslane.net> writes:
> i.e. we'd forbid:
>      initdb -D foo bar
> which the OP's error more or less devolves to.

Makes sense.  Don't we have a similar issue with psql, pg_dump, etc?
        regards, tom lane


Re: why was the VAR 'optind' never changed in initdb?

From
Andrew Dunstan
Date:

On 04/09/2012 01:38 PM, Tom Lane wrote:
> Andrew Dunstan<andrew@dunslane.net>  writes:
>> i.e. we'd forbid:
>>       initdb -D foo bar
>> which the OP's error more or less devolves to.
> Makes sense.  Don't we have a similar issue with psql, pg_dump, etc?

From a quick survey:

psql won't override a dbname or username set explicitly with an option 
argument.

pg_dump doesn't have an option argument to set the dbname.

pg_restore doesn't have an option argument to set the input file name.

vacuumdb, clusterdb, reindexdb, createlang and droplang all need 
remediation. createuser and dropuser look ok.

pg_ctl seems a mess :-( I'll need to look at it closer.


cheers

andrew




>             regards, tom lane
>