Linux: Can a signal handler excution be preempted?
c, interrupt-handling, linux, signals
Solution
The variable `errno` is thread-specific — or, more accurately, in a threaded environment, is a thread-local or per-thread value — so what is done to `errno` in this thread won't affect `errno` in other threads.
The purpose of the code saving and restoring `errno` is to hide any error set by the `write()` system call in `myhandler()`. But if the `write()` fails, it may set `errno` to some new value — it won't be zero, but that's about all you can say — but the code you're asking about reinstates the value from before the call to `write()` after the call to `write()`, so that the fact that the write occurred is 'invisible' in the sense that it does not affect `errno` for this thread.
A signal handler function may itself be interrupted by signals that are not blocked by the signal mask for the signal that it is responding to. It could also be rescheduled. Hardware interrupts can occur too, but the code will be hard pressed to notice these effects.
On Linux, you may find `/usr/include/bits/errno.h` defining the macro `errno` (wrapped in more `#ifdef` code than is shown here):
extern int *__errno_location (void) __THROW __attribute__ ((__const__));
# if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value. */
# define errno (*__errno_location ())
# endif
Problem
I came across the following signal handler code that stores the errno variable so that it wont affect main thread's errno handling. ``` void myhandler(int signo) { int esaved; esaved = errno; write(STDOUT_FILENO, "Got a signal\n", 13); errno = esaved; } ``` But this really serves the purpose ? what happens if another thread check for the shared errno varible just after write() and before restoring errno ? Will that thread get wrong errno value due to race condition? Or a signal handler executes atomically with respect to a thread/process, so that once the signal handler executes , kernel wont schedule the thread back until the signal handler finishes? Putting in other words -Once started, do a signal handler executes without being interrupted by: ``` - 1) Scheduler (process/threads), or - 2) Other signals, or - 3) Hardware interrupt handlers ? ```