cunixposixsystem-callssystems-programming

Can a read() or write() system call continue where it left off after being interrupted by an EINTR signal?


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;
}

I am wondering how this code can continue where it left off since If it receives an interrupt signal. In that case read() system call has to start again and doesn't it make it start from beginning? Same thing also valid for write() system call. Can you explain how these system call behave with those situations?


Solution

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

    If a read() is interrupted by a signal before it reads any data, it shall return -1 with errno set to EINTR.

    If a read() is interrupted by a signal after it has successfully read some data, it shall return the number of bytes read.

    In either case, the next call to read() will continue to read where it left off before the call was interrupted.

    If read() does not retrieve all the data in a message, the remaining data shall be left on the STREAM, and can be retrieved by the next read() call.