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\")\n"), progname, argv[optind + 1]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); }