3

我在我的程序中使用以下系统调用:

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() 以字节为单位返回消息的长度。如果没有消息可以接收并且对等方已经执行了有序关闭,recvfrom() 返回 0。否则该函数返回 -1 并设置 errno 以指示错误。

sendto 和 sendmsg 的情况相同。

我现在无法真正检查这一点,因为我无权访问服务器客户端设置。任何想法?

谢谢

4

2 回答 2

7

recvfrom returns -1 if it is interrupted (and sets errno to EINTR). Therefore, you should just check len:

if(len == -1) {
    if(errno == EINTR) {
        syslog(LOG_NOTICE, "recvfrom interrupted");
        goto recvagain;
    } else {
        /* some other error occurred... */
    }
}
于 2012-10-17T04:44:22.833 回答
4

成功的errno系统调用可能不会改变伪“变量”。所以你可以在你的之前清除它recvfrom,或者在len<0测试它的值的时候清除它。

有关更多信息,请参见errno(3)手册页。

实际上,正如 Robert Xiao (nneonneo) 评论的那样,您不应该errno在系统调用失败时编写并测试它(在这种情况下,C 函数 -eg recvfrometc...- 包装该系统调用会errno在返回 -1 之前编写)。

于 2012-10-17T04:54:47.740 回答