Search code examples
linuxsignalsposixsystem-callssignal-handling

Linux: does a system call have its own signal handler? Can I override it?


The document on system call read() says read() immediately returns if it is interrupted by a signal. The returned value reflects how many bytes it successfully read so far. It seems to imply some system calls have their own signal handlers.

If read() is reading from a pipe (set up by pipe()), but there is no byte available in the pipe, so read() is blocking the thread. Now, if I send a SIGINT from terminal (by Ctrl+C), the program will terminate.

Suppose at the program's start I installed a signal handler for SIGINT that prints a message "SIGINT is received". When read() is blocking and I use Ctrl+C, will the program terminate with that message printed, or will the program still terminate silently because SIGINT is already handled by read()'s signal handler?

(My experiment suggest it's the latter case.. not sure)


Solution

  • It seems to imply some system calls have their own signal handlers.

    No, Absolutely not. According to read(2) man page when read is interrupted by signal it returns EINTR. To realize this behaviour you have to handle the signal i.e. install handler for it. if you send signal without handling it then program will terminate.

    Now suppose you have handled SIGINT signal and sent it when program is blocked on read(2) then two behaviors can be observed depending on how you install signal handler.

    1. if signal is handled using sigaction(2) and SA_RESTART is used then according to signal(7) man page, handler will execute and read will be automatically restarted after the signal handler returns.
    2. If SA_RESTART flag is not used then call fails with the error EINTR.

    In both the cases program will not terminate, as SIGINT is handled.

    Suppose at the program's start I installed a signal handler for SIGINT that prints a message "SIGINT is received". When read() is blocking and I use Ctrl+C, will the program terminate with that message printed, or will the program still terminate silently because SIGINT is already handled by read()'s signal handler?

    In both the case program will not terminate. Handler message "SIGINT is received" will printed and program will continue its execution.