在被 EINTR 信号中断后,read() 或 write() 系统调用能否从中断的地方继续?

问题描述

ssize_t ret;
while (len != 0 && (ret = read (fd,buf,len)) != 0) {
  if (ret == -1) {
    if (errno == EINTR)
      continue;
    perror ("read");
    break;
  }
  len -= ret;
  buf += ret;
}

我想知道这段代码如何在收到中断信号后从中断的地方继续下去。在这种情况下, read() 系统调用必须重新开始,并且它不是从头开始吗?同样的事情也适用于 write() 系统调用。您能解释一下这些系统调用在这些情况下的表现吗?

解决方法

https://linux.die.net/man/3/read

如果 read() 在读取任何数据之前被信号中断,它将返回 -1,并将 errno 设置为 EINTR

如果一个read()在成功读取一些数据后被信号中断,它将返回读取的字节数。

在任何一种情况下,对 read() 的下一次调用都将继续从调用中断前中断的位置读取。

如果 read() 没有检索到消息中的所有数据,剩余的数据将留在 STREAM 上,并且可以在下一次 read() 调用中检索。