Unix系统中的文件read()函数

时间:2012-11-04 12:23:46

标签: c file unix

如果由于信号中断而失败,则下面的代码会重新启动read()功能。 read()从中断的地方恢复读数。因此,如果read()在读取EOF字符之前被中断,那么它将返回多少字节读取的内容?

int r_read(int fd, void *buf, int size)
{
   while((retval=read(fd,buf,size))==-1 && errno ==EINTR);
   return retval;
}  

问候。

3 个答案:

答案 0 :(得分:3)

这就是为什么读取的字节数应该保持为总数,以避免中断问题。它对非阻塞I / O也很有用。

{
    int ret = 0, nread;
    char *nbuf = (char *) buf;

    while ((nread = read(fd, nbuf, size)) != 0)
    {
        if (nread > 0)
            ret += nread, nbuf += nread, size -= nread;
        elif (errno != EINTR)
            break;
    }

    return ret;
}

答案 1 :(得分:2)

如果errno == EINTR,则表示read在根据man页面完全读取任何数据之前被中断。即从我的阅读中可以看出,状态read的{​​{1}}就像流中的数据一样没有发生。因此,似乎您可以简单地重试而不必担心丢失任何字节。我发现这有点令人惊讶,我实际上没有测试过,但这就是手册所说的。

以下是手册页中的实际文本:

  

EINTR在读取任何数据之前,呼叫被信号中断;见信号(7)。

编辑:我现在测试了这个,我发现如果我中断了读取,只有在读取任何内容之前读取被中断时才会返回EINTR。否则,它将成功返回,读取的数量少于请求的字节数。因此,要获得所需的字节数,您将需要重新启动的内容,正如另一个答案所示。

答案 2 :(得分:0)

这样没有“EOF字符”,存在文件结束条件,表示为0字节的读取。仅当read在等待某事发生时被中断时,才会设置EINTR错误,即之前底层资源会产生任何数据。

由于EOF通常会导致read停止等待并返回一个值,read无法中断这样做,如果确实如此,它将返回它所拥有的 - EOF指示符。如果在{em>等待 EOF(在底层资源宣布之前)read被中断时,它当然会返回-1并设置EINTR。