系统调用返回值和错误

时间:2012-10-17 04:39:01

标签: c linux operating-system system-calls systems-programming

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

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相同的情况。

我现在无法检查这个,因为我无法访问服务器 - 客户端设置。 有什么想法吗?

由于

2 个答案:

答案 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