Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why C library functions should fail if any signal arises

Tags:

c

signals

I am going through the book "UNIX Systems Programming", and came across the below point.

It is good practice to check for EINTR error code whenever a C library functions are called (say close() ) because the library functions can fail if any signal is received by the process. If EINTR error has occurred, the corresponding C library call should be restarted.

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

Question: Why the library function should fail if it gets a signal ? When a signal is received, the corresponding handler is called. After the completion of the handler can't the library functions continue from the point it stopped ?

like image 361
user2555646 Avatar asked Feb 26 '14 10:02

user2555646


People also ask

What C library function is used to supersede the signal function?

The sigaction() function supersedes the signal() interface, and should be the preferred usage. In particular, sigaction() and signal() must not be used in the same process to control the same signal.

Can you call a function in a signal handler?

...the signal handler calls any function in the standard library other than the abort function, the _Exit function, the quick_exit function, or the signal function with the first argument equal to the signal number corresponding to the signal that caused the invocation of the handler.

Which two signals Cannot be handled by a program and why?

(Two signals, SIGKILL and SIGSTOP , cannot be blocked. These signals also cannot be handled and, therefore, always cause their default actions.)

What is the difference between signal and sigaction?

The signal() function does not (necessarily) block other signals from arriving while the current handler is executing; sigaction() can block other signals until the current handler returns. The signal() function (usually) resets the signal action back to SIG_DFL (default) for almost all signals.


1 Answers

Why the library function should fail if it gets a Signal ?

Because that's how it's designed, and the goal is that if a signal arrives while you are stuck in a blocking system call, the system call returns, and you have a chance to act on the signal.

However, this has traditionally been implemented in many variants on different platforms.

After the completion of the handler can't the library functions continue from the point it stoped ?

Absolutely. If you want this behavior, you can set the SA_RESTART flag when you install a signal handler with sigaction().

Note, even with the SA_RESTART flag, there are still some system calls that are not automatically restarted. For Linux, you can see a list of which calls in the "Interruption of system calls and library functions by signal handlers" paragraph in the signal(7) man page . (If anyone knows a similar list defined by posix, I'd be grateful).

If you install a signal handler using signal() instead of sigaction(), it varies among unix variants whether system calls are automatically restarted or not. SySV derived platform typically does not restart system calls, while BSD dervied platform does.

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

This is actually quite dangerouos. If close() fails with EINTR, the state of the file descriptor is unknown, meaning if the file descriptor really was closed, you risk a race condition that closes another unrelated file descriptor. This is considered a bug in the posix specification.

like image 108
nos Avatar answered Oct 17 '22 14:10

nos