• 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);
        }
  • 相关阅读:
    圆角矩形“RoundRectShape”使用详解
    SVGImageView
    actionbarsherlock示例
    [百度]服务号和订阅号的区别
    [学习]ulimit
    [Cnbeta]BAT财报对比
    【百度】大型网站的HTTPS实践(三)——HTTPS对性能的影响
    【百度】大型网站的HTTPS实践(二)——HTTPS加密算法介绍
    【百度】大型网站的HTTPS实践(一)——HTTPS协议和原理
    [华商韬略] 拉里·埃里森(Larry Elison) 的传奇人生
  • 原文地址:https://www.cnblogs.com/gaojian/p/3173947.html
Copyright © 2020-2023  润新知