您的位置:首页 > 其它

wpa_cli取命令函数

2015-01-20 14:53 253 查看
int optind = 1;
int optopt;
char *optarg;
int getopt(int argc, char *const argv[], const char *optstring)
{
static int optchr = 1;
char *cp;


if (optchr == 1) {
if (optind >= argc) {
/* all arguments processed */
return EOF;
}


if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
/* no option characters */
return EOF;
}
}


if (os_strcmp(argv[optind], "--") == 0) {
/* no more options */
optind++;
return EOF;
}


optopt = argv[optind][optchr];
cp = os_strchr(optstring, optopt);
if (cp == NULL || optopt == ':') {
if (argv[optind][++optchr] == '\0') {
optchr = 1;
optind++;
}
return '?';
}


if (cp[1] == ':') {
/* Argument required */
optchr = 1;
if (argv[optind][optchr + 1]) {
/* No space between option and argument */
optarg = &argv[optind++][optchr + 1];
} else if (++optind >= argc) {
/* option requires an argument */
return '?';
} else {
/* Argument in the next argv */
optarg = argv[optind++];
}
} else {
/* No argument */
if (argv[optind][++optchr] == '\0') {
optchr = 1;
optind++;
}
optarg = NULL;
}
return *cp;
}

假设命令是./wpa_cli -p /home/work/pkg_wifi -i wlan0

则char *const argv[] 即为------argv[0]="./wpa_cli",argv[1]="-p",argv[2]="/home/work/pkg_wifi",argv[3]="-i",argv[4]="wlan0" argc=5

和optstring做对比,optstring="a:Bg:G:hi:p:P:v"

[cpp]
view plaincopy

static int optchr = 1;
char *cp;


if (optchr == 1) {
if (optind >= argc) {
/* all arguments processed */
return EOF;
}

optind<5不成立

[cpp]
view plaincopy

if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
/* no option characters */
return EOF;
}

argv[1][0]="-",argv[1]="p"这里防止不规范的输入

[cpp]
view plaincopy

if (os_strcmp(argv[optind], "--") == 0) {
/* no more options */
optind++;
return EOF;
}

比较argv[1]和"--"相同则返回0,这里不相同

[cpp]
view plaincopy

optopt = argv[optind][optchr];
cp = os_strchr(optstring, optopt);
if (cp == NULL || optopt == ':') {
if (argv[optind][++optchr] == '\0') {
optchr = 1;
optind++;
}
return '?';
}

optopt=argv[1][1]="p"=112(ASC)
os_strchr是查找字符的函数,是C库的标准函数,原型是strchr,这里wpa_supplicant做了两种方案,一种是自己实现的,一种是宏定义了strchr,这么做的原因还没看。

strchr()如果找到了字符'p',这里用ASC码做了强制转换,就返回该字符出现的地址,否则返回0。这里内部的处理要看main函数代码。

[cpp]
view plaincopy

if (cp[1] == ':') {
/* Argument required */
optchr = 1;
if (argv[optind][optchr + 1]) {
/* No space between option and argument */
optarg = &argv[optind++][optchr + 1];
} else if (++optind >= argc) {
/* option requires an argument */
return '?';
} else {
/* Argument in the next argv */
optarg = argv[optind++];
}
}

cp="p:P:v",cp[1]=':',argv[1][2]=0。这里如果argv[1][2]=1,那么表示-p,-i 等命令后面没有跟上空格,就成

了argv[0]="./wpa_cli",argv[1]="-p/home/work/pkg_wifi",argv[2]="-iwlan0"那么就将argv[1][3]赋给optarg,

argv[1][3]='/',后面就会直接返回cp,cp="p:P:v",这时optarg=argv[1][3]='/home/work/pkg_wifi'

当argv[1][2]=0时,判断if (++optind >= argc),即2>=5,这里判断有几个参数。然后执行optarg = argv[2]="/home/work/pkg_wifi";

else {

/* No argument */

if (argv[optind][++optchr] == '\0') {

optchr = 1;

optind++;

}

这里表示没有参数的情况,即-B,-v,-h,后台运行,版本信息和帮助。argv[1][1]='p'。optarg = NULL;返回cp="p:P:v"。因为函数的返回值

是int型的,所以返回p的ASC码。在main函数中

case 'p':

ctrl_iface_dir = optarg;

break;

将optarg赋值给ctrl_iface_dir=optarg = argv[2]="/home/work/pkg_wifi"。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: