read()
如果由于信号中断而失败,下面的代码将重新启动该功能。从中断的read()
地方继续读取。因此,如果read()
在读取字符之前被中断EOF
,它将返回它读取的多少字节?
int r_read(int fd, void *buf, int size)
{
while((retval=read(fd,buf,size))==-1 && errno ==EINTR);
return retval;
}
问候。
这就是为什么读取的字节数应该保持为一个总数,以避免中断问题。它对于非阻塞 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;
}
如果errno == EINTR
,则表示read
它在根据man
页面读取任何数据之前就被中断了。即从我的阅读来看,就流中的数据而言,就好像没有发生read
状态。EINTR
因此,您似乎可以简单地重试,而不必担心丢失任何字节。我觉得这有点令人惊讶,而且我还没有实际测试过,但这就是手册所说的。
以下是手册页中的实际文本:
EINTR 在读取任何数据之前调用被信号中断;见信号(7)。
编辑:我现在对此进行了测试,我发现如果我中断了读取,EINTR
只有在读取任何内容之前被中断时才会返回。否则,它将成功返回,读取的字节数少于请求的字节数。因此,要获得所需的字节数,您将需要重新启动的东西,正如另一个答案所示。
没有这样的“EOF 字符”,存在文件结束条件,表示读取 0 字节。read
只有在等待某事发生时被中断,即在底层资源产生任何数据之前,才会设置 EINTR 错误。
由于 EOF 通常会导致read
停止等待并返回一个值,read
因此不能被中断,如果这样做,它只会返回它所拥有的 - EOF 指示符。如果在等待read
EOF时被中断(在底层资源宣布之前),它当然会返回 -1 并设置 EINTR。