I am reading APUE and the Interrupted System Calls chapter confuses me.
I would like to write down my understanding based on the book, please correct me.
A characteristic of earlier UNIX systems was that if a process caught a signal while the process was blocked in a ‘‘slow’’ system call, the system call was interrupted. The system call returned an error and
errno
was set toEINTR
. This was done under the assumption that since a signal occurred and the process caught it, there is a good chance that something has happened that should wake up the blocked system call.So it's saying that the earlier UNIX systems has a feature: if my program uses a system call, it would be interrupted/stopped, if at any time the program catches a signal. (Does default handler also count as a catch?)
For example, if I have a
read
system call, which reads 10GB data, when it's reading, I send any one of signals(e.g.kill -SIGUSR1 pid
), thenread
would fail and return.
To prevent applications from having to handle interrupted system calls, 4.2BSD introduced the automatic restarting of certain interrupted system calls. The system calls that were automatically restarted are
ioctl
,read
,readv
,write
,writev
,wait
, andwaitpid
. As we’ve mentioned, the first five of these functions are interrupted by a signal only if they are operating on a slow device;wait
andwaitpid
are always interrupted when a signal is caught. Since this caused a problem for some applications that didn’t want the operation restarted if it was interrupted, 4.3BSD allowed the process to disable this feature on a per-signal basis.
So before automatic restarting was introduced, I had to handle interrupted system call on my own. I need write code like:
The problem with interrupted system calls is that we now have to handle the error return explicitly. The typical code sequence (assuming a read operation and assuming that we want to restart the read even if it’s interrupted) would be:
again:
if ((n = read(fd, buf, BUFFSIZE)) < 0) {
if (errno == EINTR)
goto again; /* just an interrupted system call */
/* handle other errors */
}
But nowadays I don't have to write this kind of code, beacause of the automatic restarting mechanism.
So if I my understanding are all correct, what/why should I care about interrupted system call now..? It seems the system/OS handles it automatically.
EINTR
: is there a rationale behind it?