Reputation: 1
I'm reading integers from a file in this way:
int v, num;
for(;;) {
v = read(fd, &num, sizeof(int));
if (v == -1) {
fprintf(stderr, "Error in read()\n");
exit(EXIT_FAILURE);
}
if (v == 0)
break;
[...]
}
What does it happen if a signal arrives? How can I manage errno == EINTR? Do I have to repeat read if errno==EINTR?
Upvotes: 0
Views: 501
Reputation: 21213
If you didn't mess with signals, you don't have to worry about it. Here's why: a signal's action is either terminate, ignore, or invoke a handler (or stop / continue, but let's ignore these), so, unless you explicitly caught any signal, then you will never have to think about EINTR
- it will only happen if read(2)
was interrupted by a signal handler that you set up, was invoked and returned.
If you caught a signal, then whether or not slow syscalls are automatically restarted is controlled by the SA_RESTART
flag that can be set/unset in the sa_flags
field of struct sigaction
before setting the signal handler. If you want read(2)
and others to automatically restart after the handler returns, then you must specify this flag to keep code portable (the default behavior varies across platforms).
Under some conditions, there are a couple of interfaces that are not automatically restarted even if SA_RESTART
is set; refer to man 7 signal
to see a list.
In case you're wondering: slow syscalls are syscalls that can block forever under certain conditions: for example, read()
s from a terminal or socket, open(2)
on FIFOs, wait(2)
and family, file locking interfaces, some ioctl(2)
calls, etc.
Upvotes: 0