命令源码解析
uid = getuid();
if (setuid(uid)) {
perror("ping: setuid");
exit(-1);
}
while ((ch = getopt(argc, argv, COMMON_OPTSTR "bRT:")) != EOF){
switch(ch) {
case 'b':
broadcast_pings = 1;
break;
case 'Q':
settos = parsetos(optarg);
if (settos &&
(setsockopt(icmp_sock, IPPROTO_IP, IP_TOS,
(char *)&settos, sizeof(int)) < 0)) {
perror("ping: error setting QOS sockopts");
exit(2);
}
break;
case 'R':
if (options & F_TIMESTAMP) {
fprintf(stderr, "Only one of -T or -R may be used\n");
exit(2);
}
options |= F_RROUTE;
break;
case 'T':
if (options & F_RROUTE) {
fprintf(stderr, "Only one of -T or -R may be used\n");
exit(2);
}
options |= F_TIMESTAMP;
if (strcmp(optarg, "tsonly") == 0)
ts_type = IPOPT_TS_TSONLY;
else if (strcmp(optarg, "tsandaddr") == 0)
ts_type = IPOPT_TS_TSANDADDR;
else if (strcmp(optarg, "tsprespec") == 0)
ts_type = IPOPT_TS_PRESPEC;
else {
fprintf(stderr, "Invalid timestamp type\n");
exit(2);
}
break;
case 'I':
{
#if 0
char dummy;
int i1, i2, i3, i4;
if (sscanf(optarg, "%u.%u.%u.%u%c",
&i1, &i2, &i3, &i4, &dummy) == 4) {
__u8 *ptr;
ptr = (__u8*)&source.sin_addr;
ptr[0] = i1;
ptr[1] = i2;
ptr[2] = i3;
ptr[3] = i4;
options |= F_STRICTSOURCE;
} else {
device = optarg;
}
#else
if (inet_pton(AF_INET, optarg, &source.sin_addr) > 0)
options |= F_STRICTSOURCE;
else
device = optarg;
#endif
break;
}
case 'M':
if (strcmp(optarg, "do") == 0)
pmtudisc = IP_PMTUDISC_DO;
else if (strcmp(optarg, "dont") == 0)
pmtudisc = IP_PMTUDISC_DONT;
else if (strcmp(optarg, "want") == 0)
pmtudisc = IP_PMTUDISC_WANT;
else {
fprintf(stderr, "ping: wrong value for -M: do, dont, want are valid ones.\n");
exit(2);
}
break;
case 'V':
printf("ping utility, iputils-ss%s\n", SNAPSHOT);
exit(0);
COMMON_OPTIONS
common_options(ch);
break;
default:
usage();
}
}
argc -= optind;
argv += optind;
getopt会做下面几件事
1/对argv进行分析,每次返回一个argv[i]
2/解析成功,optind加1
3/解析不成功,将argv[i]放入argv的后面
4/接着分析-a 后面的参数,以optarg代入,且一个 -a 后面只能跟一个参数