4

Is far as I remember, read() cannot be interrupted by a signal and return with errno=EINTR when reading from a regular file, and likewise for write() when writing to a regular file.

That is opposed to reading from, or writing to terminals, pipes, sockets, etc.

Is this correct on Linux?

Is this mandated by POSIX?

EDIT: Assume that we are talking about interruption by a signal that is not configured to automatically restart system calls.

Kristian Spangsege
  • 2,903
  • 1
  • 20
  • 43

2 Answers2

1

Yes, both Posix and Linux man pages allows interrupted reads: Posix read and Linux read. Posix page states:

The issue of which files or file types are interruptible is considered an implementation design issue. This is often affected primarily by hardware and reliability issues.

Linux man page on signals guarantees that it can happen on "slow" devices only:

read(2), readv(2), write(2), writev(2), and ioctl(2) calls on "slow" devices. A "slow" device is one where the I/O call may block for an indefinite time, for example, a terminal, pipe, or socket.

Mac OS X agrees for its read:

[EINTR] A read from a slow device was interrupted before any
        data arrived by the delivery of a signal.

but it's not confirmed for its write.

FreeBSD read too:

 [EINTR] A read from a slow device (i.e.  one that might block
      for an arbitrary amount of time) was interrupted by
      the delivery of a signal before any data arrived.

but again no mentioning of "slow devices" for write.

All in all, for normal files on majority of systems read should work without problems, regarding write it's not confirmed.

0

Practically speaking, most programs expect this behavior, but if EINTR did happen the result code would indicate how many bytes were actually read, maybe zero. So if you've coded defensively to handle a short read correctly (with a loop to advanxe the pointer by n retry with len - n), then you'd not even notice. I always put network reads in loops for this reason. And since everything is a file, you can't really know that your caller didn't give you a TCP connection, so best expect short reads.

I am not a spec lawyer, so I don't know or care what the spec says. Realistically, it doesn't happen... unless it does.

Jeff Allen
  • 1,391
  • 13
  • 19
  • Jeff, I think you are talking about short reads here, which is not what my question is about. My question is about interruption before anything at all is read. Note that `read()` is only allowed to fail with `EINTR` if nothing has been read at all. If something has been read (a short read), `read()` must succeed. – Kristian Spangsege Feb 08 '16 at 10:54
  • Whether there is also a rule, that says that you can never get a short read from a regular file, is an interesting question, but it is not the question I am asking here. – Kristian Spangsege Feb 08 '16 at 10:56