Hardware Reference
In-Depth Information
The Unix solution to this problem is to have the kernel return an error code
EINTR
after a signal handler receives a signal. In this manner, the
read(2)
call returns an error,
allowing the application program to test whether it received a signal. The following code
shows how the simple
read(2)
call is replaced with a loop that checks whether the signal
handler was called:
do {
rc = read(fd, buf, n); /* Block until n bytes read */
if ( is_signaled )
longjmp(shutdown,1); /* Shutdown this server */
} while ( rc == -1 && errno == EINTR );
if ( rc == -1 ) { /* Check for non EINTR errors */
fprintf(stderr,"%s: read(2)\n",strerror(errno));
abort();
}
In this code snippet, we see that the
read(2)
call is performed as part of a loop.
As long as an error is returned
and the
errno
value is
EINTR
, we check for any interesting
events (like
is_signaled
) and repeat the call. If any other type of error occurs or we
succeed, we drop out of the loop.
This is the basic template that should be used for any call that might receive
EINTR
,
even if you don't plan to handle signals in your application. Otherwise, you may find that
your Pi application may run for weeks and then one day when you least expect it, fail
because of a received
EINTR
error.