Course contentsShow
← Linux
Lesson 489 of 1,8195. Process Management and SignalingFree lesson

Signal Blocking and System Calls

Describe how system calls are interrupted by signals and the logic required to restart them.

In this lesson, you will learn why Linux system calls can be interrupted by signals and how you can gracefully handle the resulting errors to ensure your program doesn’t crash.

When Signals Interrupt the Kernel

When a process executes a system call (like read() to wait for input or sleep() to pause), it enters a "blocked" state inside the kernel. If a signal is delivered to that process while it is waiting, the kernel must pause the system call to allow your signal handler to run.

Once your signal handler finishes, the system call cannot simply resume as if nothing happened because its internal state might have been compromised. Instead, the kernel aborts the system call and returns a specific error to your program: EINTR (Interrupted system call).

The Logic of Restarting

If your program receives an EINTR error, it doesn't necessarily mean the operation failed permanently. It just means the kernel was distracted. To handle this, you must implement a "retry loop" logic.

Consider this pattern for a read operation:

ssize_t result;
do {
    result = read(fd, buffer, sizeof(buffer));
} while (result == -1 && errno == EINTR);

if (result == -1) {
    perror("Actual read failure");
}

By checking if errno equals EINTR, you detect that a signal was the culprit. The do-while loop then immediately re-invokes the system call, allowing the kernel to resume the waiting process exactly where it left off.

Why not just restart automatically?

You might wonder why the kernel doesn't just restart the system call for you. In many cases, it actually can (this is often configurable via flags like SA_RESTART when setting up a signal handler). However, relying on automatic restarts isn't always safe. For complex interactions—like writing to a network socket or reading from a pipe—you often need to manually verify how much data was successfully processed before the interruption occurred. Handling EINTR explicitly gives your program the control it needs to maintain data integrity during asynchronous signal arrival.

Key Takeaway: When a system call fails with EINTR, it is not a fatal error; it is a signal to your program to safely restart the interrupted operation.