Why C library functions should fail if any signal occurs

I look through the book "System Programming UNIX" and came across a low point.

It is good practice to check the EINTR error code whenever a C library function is called (for example, close() ), because library functions can fail if any signal is received by the process. If an EINTR error occurs, you must restart the corresponding C library call.

 while ((close(fd) == -1) && errno == EINTR); // close is restarted if it fails with EINTR error. 

Question: Why does the library function not work if it receives a signal? When a signal is received, the corresponding handler is called. After the handler completes, is it impossible for library functions to continue from the moment they stop?

+6
source share
1 answer

Why does the library function not work if it receives a signal?

Because it was designed that way, and the goal is that if a signal arrives while you are stuck in a system lock call, the system call returns, and you have the ability to act on the signal.

However, this is traditionally implemented in many versions on different platforms.

After the handler completes, is it impossible for library functions to continue from the moment they stop?

That's right. If you want this behavior, you can set the SA_RESTART flag when setting the signal handler using sigaction ().

Note that even with the SA_RESTART flag, there are still system calls that do not restart automatically. For Linux, you can see the call list in the section "Interrupting System Calls and Library Functions Using Signal Handlers" on the signal (7) man page. (If anyone knows of a similar list defined by posix, I would be grateful).

If you install a signal handler using signal () instead of sigaction() , it may vary depending on unix options, whether system calls are automatically reloaded or not. The original SySV platform usually does not restart system calls, while the BSD-protected platform does.

while ((close (fd) == -1) & errno == EINTR); // closing will restart if it is not with an EINTR error.

This is actually quite dangerous. If the close () function does not work with EINTR, the state of the file descriptor is not known, which means that if the file descriptor was actually closed, you risk a race condition that closes another unrelated file descriptor. This is considered a bug in the posix specification.

+7
source

All Articles