1
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?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Kamil Kaya
  • 47
  • 5

1 Answers1

2

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.

Devolus
  • 21,661
  • 13
  • 66
  • 113
  • 1
    IMO It's pretty plain from that definition. If there is no data read, it will return -1. If there was data read, then it returns the number of bytes read. In either way it continues to read where it left off. – Devolus Apr 07 '21 at 14:30
  • 2
    It seem that "continues to read where it left off" does answer the question. – William Pursell Apr 07 '21 at 14:32
  • It continues where it left off, so in the first case was nothing read, so it will keep reading whereever it was before the call started. In the second case it will return the number of bytes read, so the next read will continue reading after where the bytes returned left off. – Devolus Apr 07 '21 at 14:32
  • @KonradRudolph, I gave the link, and there are other sources, saying the same. – Devolus Apr 07 '21 at 14:34
  • @KonradRudolph It comes from the comment. The comment to which you responded "Your comment ... still ignores the ... actual question". I don't disagree that this answer is incomplete, but the comment does clarify somewhat. – William Pursell Apr 07 '21 at 14:37
  • @WilliamPursell, I updated the answer to include that comment, to make it clearer. – Devolus Apr 07 '21 at 14:38
  • @WilliamPursell The comment was originally not part of the answer, it was added later. Furthermore, you (and the answerer) seem to misunderstand the quoted section: it says nothing about subsequent calls to `read` *after* an `EINTR` signal was handled. It only concerns the interrupted call *itself*. — Devolus’ comment may well be right (these semantics seem reasonable) but I can’t find any confirmation of this. – Konrad Rudolph Apr 07 '21 at 14:39
  • 2
    `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. ` – Devolus Apr 07 '21 at 14:40
  • @KonradRudolph, I added it to the answer aswell, though I think that my original answer was already sufficient. ;) – Devolus Apr 07 '21 at 14:42
  • Nice and clean explanation. Thx for information. – Kamil Kaya Apr 08 '21 at 11:17