Introduction Signal Handling in C refers to the process of catching and responding to runtime events like division by zero, segmentation faults, or interrupts (e.g., pressing Ctrl+C). A signal acts as a notification that the operating system sends to a process, informing it that something significant has occurred — often requiring the program to respond or shut down safely. Understanding Signal Handling in C helps developers build resilient software that can manage errors, clean up resources, and exit gracefully. Without proper handling, a C program might crash unexpectedly or leave memory leaks behind. Why Study This Topic? In real-world systems, unpredictable events often occur—like a user pressing Ctrl+C or a system issuing a segmentation fault. Handling these signals gracefully ensures the program terminates safely or recovers appropriately. Real-time fun example:Think of signal handling like a fire alarm in a school. When the alarm rings (signal), the ongoing class (program flow) is interrupted, and students follow a fire drill (handler function) to exit safely. Without this plan, chaos ensues! What Will Be Covered? What are signals in C Common types of signals Using signal() function Using sigaction() for advanced handling Creating custom signal handlers Real-time examples and use cases Best practices and safety tips What Are Signals? A signal is a notification sent to a process by the OS to notify it of events like division by zero, segmentation fault, or user interrupt. Common Signals in C SignalDescriptionConstantInterruptCtrl+CSIGINTTerminateKill from OSSIGTERMSegmentationInvalid memory accessSIGSEGVArithmeticDivision by zero, etc.SIGFPEAlarmTimer expiredSIGALRM Handling Signals with signal() Function You can use the signal() function to catch signals and run a specific handler function when a signal occurs. Syntax void (*signal(int signum, void (*handler)(int)))(int); signum: The signal number (e.g., SIGINT) handler: The function that handles the signal Example: Handling Ctrl+C #include <stdio.h> #include <signal.h> void handler(int signum) { printf("Caught signal %d\n", signum); } int main() { signal(SIGINT, handler); while (1); // Program waits indefinitely; press Ctrl+C to test return 0; } Explanation The program runs until you press Ctrl+C. When the OS sends SIGINT, the program runs the handler() function instead of exiting immediately. This allows you to manage clean-up or give custom messages. Limitations of signal() On some systems, it resets the handler after catching a signal once. It doesn’t allow signal blocking or detailed behavior control. To gain more control, use sigaction(). Advanced Handling with sigaction() The sigaction() function offers better control and safer signal handling. Syntax int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); signum: Signal to handle act: Defines the new behavior oldact: Optionally stores the previous behavior Example: Handling SIGINT Safely #include <stdio.h> #include <signal.h> #include <string.h> void handler(int signum) { printf("Handled signal %d safely.\n", signum); } int main() { struct sigaction act; memset(&act, 0, sizeof(act)); act.sa_handler = handler; sigaction(SIGINT, &act, NULL); while (1); // Press Ctrl+C to see the custom message return 0; } Explanation sigaction() installs the handler function for SIGINT. memset() clears the sigaction struct before use. The custom handler runs every time you press Ctrl+C, without resetting. Ignoring or Restoring Signals signal(SIGINT, SIG_IGN); // Ignore Ctrl+C signal(SIGINT, SIG_DFL); // Restore default behavior Best Practices Keep handlers short and non-blocking. Avoid using printf() in handlers; use write() instead. Use sigaction() for reliability. Reinstall handler if using signal() on older systems. Do not perform memory allocation inside handlers. Summary Signals are software interrupts from the OS or user. signal() is simple, but sigaction() is more robust. You can catch, ignore, or restore signal behavior. Proper signal handling prevents data corruption and allows graceful exits. Learning Outcomes After completing this topic, learners will: Understand what signals are and how they function Use signal() and sigaction() to create custom handlers Identify and respond to various system-generated signals Write safe and effective signal-handling code Apply best practices for interrupt-driven programming Common Interview Questions Q1. What is signal handling in C?A: It allows a program to handle asynchronous events like interrupts.Asked in: Infosys, Capgemini Q2. What’s the difference between signal() and sigaction()?A: sigaction() provides more reliable and flexible signal handling.Asked in: TCS, Cognizant Q3. What happens when a signal is ignored?A: The process continues its execution uninterrupted.Asked in: Wipro, IBM Q4. Can we assign custom functions to handle signals?A: Yes, using signal() or sigaction().Asked in: Zoho, Accenture Q5. Is it safe to use printf() in a signal handler?A: No, because it’s not async-signal-safe. Use write() instead.Asked in: Tech Mahindra, HCL Practice Exercises Coding Challenge: Write a C program that catches both SIGINT and SIGTERM using sigaction(). Log a message and exit cleanly. Scenario You're building a file server in C. If a client suddenly disconnects or presses Ctrl+C during upload, your program shouldn't crash. Instead, it should catch the interrupt signal, save logs, close open files, and exit gracefully—exactly what proper signal handling ensures. [quiz-cat id="21229"] Additional Resources GNU C Signal Handling Guide Book: Advanced C Programming by Peter van der Linden Tool: Signal Explorer (Online Linux sandbox for testing signals)