PostgreSQL的 initdb 源代码分析之三

继续

其实接前面,整个while循环是这样的:

    while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index)) != -1)
    {
        switch (c)
        {
                     ......
                }
                
                ......
         }

这一句,c = getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index),

除了获得initdb 后跟着的是 -D 还是 -E之类的,还有一个用途,就是给 全局变量 optarg 赋值。这个全局变量其实挺坑爹的。

/*
 * getopt_long
 *    Parse argc/argv argument vector, with long options.
 *
 * This implementation does not use optreset.  Instead, we guarantee that
 * it can be restarted on a new argv array after a previous call returned -1,
 * if the caller resets optind to 1 before the first call of the new series.
 * (Internally, this means we must be sure to reset "place" to EMSG before
 * returning -1.)
 */
int
getopt_long(int argc, char *const argv[],
            const char *optstring,
            const struct option * longopts, int *longindex)
{
    ......
    if (!*place)
    {                            /* update scanning pointer */
        ......

        if (place[0] && place[0] == '-' && place[1])
        {
            ......for (i = 0; longopts[i].name != NULL; i++)
            {
                if (strlen(longopts[i].name) == namelen
                    && strncmp(place, longopts[i].name, namelen) == 0)
                {
                    if (longopts[i].has_arg)
                    {
                        if (place[namelen] == '=')
                            optarg = place + namelen + 1;
                        else if (optind < argc - 1)
                        {
                            optind++;
                            optarg = argv[optind];
                        }
                        else
                        {
                            ......
                        }
                    }
                    else
                    {
                        ......
                    }

                    ......
                }
            }
            ......
        }
    }

    ......

    if (oli[1] != ':')
    {                            /* don't need argument */        ......
    }
    else
    {                            /* need an argument */
        if (*place)                /* no white space */
            optarg = place;
        else if (argc <= ++optind)
        {                        /* no arg */            ......
        }
        else
            /* white space */
            optarg = argv[optind];
        place = EMSG;
        ++optind;
    }
    return optopt;
}

我经过运行,得到的是:

optarg 变量的值为  /home/pgsql/DemoDir。

通过下面的代码,pg_data 被赋值为  /home/pgsql/DemoDir。

    /* process command-line options */

    while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index)) != -1)
    {
        switch (c)
        {
            case 'A':
                authmethod = xstrdup(optarg);
                break;
            case 'D':

                pg_data = xstrdup(optarg);
                break;
                         ......
                 }
                 ......
         }

继续分析。

main函数的下一段,其中的 optiond,也是由前面的  getopt_long 函数计算出来的,我运行时候,其值为 3。

如下代码,是异常处理,可以跳过。

    if (optind < argc)
    {
        pg_data = xstrdup(argv[optind]);
        optind++;
    }
if (optind < argc)
    {
        fprintf(stderr, _("%s: too many command-line arguments (first is "%s")
"),
                progname, argv[optind + 1]);
        fprintf(stderr, _("Try "%s --help" for more information.
"),
                progname);
        exit(1);
    }
原文地址:https://www.cnblogs.com/gaojian/p/3173947.html