我在我的程序中使用以下系统调用:
recvfrom
sendto
sendmsg
从上面提到的每个系统调用中,我检查它是否完成没有任何中断,如果它被中断,我重试。
例如:
recvagain:
len = recvfrom(fd, response, MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen);
if (errno == EINTR) {
syslog(LOG_NOTICE, "recvfrom interrupted: %s", strerror(errno));
goto recvagain;
}
这里的问题是我需要在每次失败时将errno值重置为0。或者如果recvfrom()成功,它会将errno重置为0吗?
recvfrom()手册页说:
成功完成后,recvfrom()以字节为单位返回消息的长度。如果没有可以收到的消息和 peer已执行有序关闭,recvfrom()返回0。 否则,该函数返回-1并设置errno以指示 错误。
与sendto和sendmsg相同的情况。
我现在无法检查这个,因为我无法访问服务器 - 客户端设置。 有什么想法吗?
由于
答案 0 :(得分:7)
recvfrom
如果被中断则返回-1
(并将errno
设置为EINTR
)。因此,您应该只检查len
:
if(len == -1) {
if(errno == EINTR) {
syslog(LOG_NOTICE, "recvfrom interrupted");
goto recvagain;
} else {
/* some other error occurred... */
}
}
答案 1 :(得分:4)
成功的系统调用可能不会更改errno
伪“变量”。因此,您可以在recvfrom
之前或len<0
之前清除它并测试其值。
有关详情,请参阅errno(3)手册页。
实际上,正如Robert Xiao(nneonneo)评论的那样,你不应该写errno
并在系统调用失败时测试它(在这种情况下,C函数-eg recvfrom
等... - 在返回-1之前包装该系统调用将写入errno
。