【发布时间】:2016-10-20 00:22:46
【问题描述】:
我正在学习 C 中的 ping 源代码。
在此我被视为一行。即 if 条件后跟 while(0)。
我在互联网上被搜索过。他们只给 line do 后跟 while(0) 。对于 do 后跟 while(0),我知道答案。但我不知道条件是否后跟 while(0)。
示例代码是,
if (source.sin_addr.s_addr == 0) {
socklen_t alen;
struct sockaddr_in dst = whereto;
int probe_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (probe_fd < 0) {
perror("socket");
exit(2);
}
if (device) {
struct ifreq ifr;
int rc;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, device, IFNAMSIZ-1);
enable_capability_raw();
rc = setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1);
disable_capability_raw();
if (rc == -1) {
if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
struct ip_mreqn imr;
if (ioctl(probe_fd, SIOCGIFINDEX, &ifr) < 0) {
fprintf(stderr, "ping: unknown iface %s\n", device);
exit(2);
}
memset(&imr, 0, sizeof(imr));
imr.imr_ifindex = ifr.ifr_ifindex;
if (setsockopt(probe_fd, SOL_IP, IP_MULTICAST_IF, &imr, sizeof(imr)) == -1) {
perror("ping: IP_MULTICAST_IF");
exit(2);
}
} else {
perror("ping: SO_BINDTODEVICE");
exit(2);
}
}
}
if (settos &&
setsockopt(probe_fd, IPPROTO_IP, IP_TOS, (char *)&settos, sizeof(int)) < 0)
perror("Warning: error setting QOS sockopts");
dst.sin_port = htons(1025);
if (nroute)
dst.sin_addr.s_addr = route[0];
if (connect(probe_fd, (struct sockaddr*)&dst, sizeof(dst)) == -1) {
if (errno == EACCES) {
if (broadcast_pings == 0) {
fprintf(stderr, "Do you want to ping broadcast? Then -b\n");
exit(2);
}
fprintf(stderr, "WARNING: pinging broadcast address\n");
if (setsockopt(probe_fd, SOL_SOCKET, SO_BROADCAST,
&broadcast_pings, sizeof(broadcast_pings)) < 0) {
perror ("can't set broadcasting");
exit(2);
}
if (connect(probe_fd, (struct sockaddr*)&dst, sizeof(dst)) == -1) {
perror("connect");
exit(2);
}
} else {
perror("connect");
exit(2);
}
}
alen = sizeof(source);
if (getsockname(probe_fd, (struct sockaddr*)&source, &alen) == -1) {
perror("getsockname");
exit(2);
}
source.sin_port = 0;
#ifndef WITHOUT_IFADDRS
if (device) {
struct ifaddrs *ifa0, *ifa;
int ret;
ret = getifaddrs(&ifa0);
if (ret) {
fprintf(stderr, "gatifaddrs() failed.\n");
exit(2);
}
for (ifa = ifa0; ifa; ifa = ifa->ifa_next) {
if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET)
continue;
if (!strncmp(ifa->ifa_name, device, sizeof(device) - 1) &&
!memcmp(&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
&source.sin_addr, sizeof(source.sin_addr)))
break;
}
freeifaddrs(ifa0);
if (!ifa)
fprintf(stderr, "ping: Warning: source address might be selected on device other than %s.\n", device);
}
#endif
close(probe_fd);
} while (0);
在 if 条件之后,他们使用 while(0)。这有什么用。
谁能解释一下。
【问题讨论】:
-
对我来说看起来像是一个无害的错字。也许代码是一个 do/while 循环,有人将
do更改为if。 -
能发下源链接吗?
-
也许可以稍微缩短一下上面的代码,用“…”标记遗漏的代码?就像现在一样,大部分代码与您的具体问题无关。
-
这是来自 iputils 中的 ping.c。令人惊讶的是,代码审计没有发现这一点。它已经存在了至少 10 年。