我和我的朋友在理解代码方面有问题。我们不明白为什么最后要检查nread是否为!= 1。谁能帮助我们,我们将非常高兴。
while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
if (nread == -1 && errno != EAGAIN) quit("read");
}
只在读取成功后才退出循环。
也就是说,代码有bug。
对read
的调用返回下列结果之一:
- -1出错
- 0, on EOF。
- [1,
count
],读取字节数。
由于对read
的特定调用只尝试读取一个字节,因此返回的可能值如下:
- -1出错
- 0, on EOF。
- 1,读取成功。
那么,让我们把这个代码片段作为一个整体来看一下。
- 如果不是EAGAIN,则退出。 如果出现EAGAIN错误,则重试。如果失败了,它会再次尝试。
- 如果读取成功,则继续超出循环。
这是有问题的,原因有两个。
-
它对EAGAIN的处理不正确
当没有可用数据时,对于非阻塞句柄返回EAGAIN。因此,这是一个繁忙等待循环(占用CPU)。这是不能接受的。
另外,如果句柄可以是套接字,则可以返回EWOULDBLOCK而不是EAGAIN。
-
其对EOF的处理不正确
在EOF时,它尝试再次读取。这是不好的。
现在,可以在某些句柄返回EOF后读取它们。具体来说,终端可以在返回EOF后重置其EOF状态。但是不能保证STDIN是终端。即使知道STDIN是一个终端,它仍然可以像任何其他句柄一样返回一个无止尽的EOF流。