如果由于信号中断而失败,则下面的代码会重新启动read()
功能。 read()
从中断的地方恢复读数。因此,如果read()
在读取EOF
字符之前被中断,那么它将返回多少字节读取的内容?
int r_read(int fd, void *buf, int size)
{
while((retval=read(fd,buf,size))==-1 && errno ==EINTR);
return retval;
}
问候。
答案 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。