C signal handling

Created By: chatGPT

Signal handling in C is a crucial aspect of managing asynchronous events that occur during program execution. Understanding how to manage these signals allows your program to gracefully handle errors, interruptions, and other events that may arise. Signals are sent by the operating system to inform a process that a certain event has occurred, such as an interrupt from the keyboard or a division by zero error. To handle signals, you will typically use the signal or sigaction functions. Here’s a brief overview of how to set up a signal handler using both methods.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void handle_sigint(int sig) {
    printf("Caught signal %d: Ctrl+C pressed\n", sig);
    exit(1);
}

int main() {
    signal(SIGINT, handle_sigint); // Using signal()
    
    // Alternatively, using sigaction:
    // struct sigaction sa;
    // sa.sa_handler = handle_sigint;
    // sigemptyset(&sa.sa_mask);
    // sa.sa_flags = 0;
    // sigaction(SIGINT, &sa, NULL);
    
    printf("Press Ctrl+C to trigger signal handler...\n");
    while (1) {
        // Infinite loop to keep program running
    }
    return 0;
}

In the example above, we define a signal handler function called handle_sigint that gets called when the SIGINT signal is received, typically generated when the user presses Ctrl+C. In the main function, we set up our signal handler by passing handle_sigint to the signal function.

Alternatively, you can use sigaction, which offers more control over signals by allowing you to specify additional behavior via its options. To set this up, you would define a struct sigaction, assign your handler to it, and then call sigaction with the desired signal. This is often recommended due to its robustness compared to signal. Here’s the setup using sigaction.

struct sigaction sa;
sa.sa_handler = handle_sigint;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);

It’s important to note that some signals, like SIGKILL and SIGSTOP, cannot be caught or ignored. Additionally, when writing a signal handler, keep in mind that the handler must execute quickly and avoid using non-reentrant functions, as they can lead to undefined behavior.

In this context, using functions like printf inside the signal handler is discouraged unless you are sure of their safety. A more robust approach is to set a flag in the handler and handle the required work outside of the handler context during periodic checks in your main program loop.

volatile sig_atomic_t flag = 0;

void handle_sigint(int sig) {
    flag = 1; // Set flag
}

int main() {
    signal(SIGINT, handle_sigint);
    while (!flag) {
        // Main loop
    }
    printf("Signal received, exiting\n");
    return 0;
}
Summary: Signal handling in C is an essential skill for writing robust applications. By using signal or sigaction, you can effectively manage signals and ensure your application handles events or errors gracefully. Always remember to consider the implications of functions used within signal handlers to maintain the stability of your program.
Introduction And SetupVariablesData TypesIntFloatDoubleCharVoidUnsignedSignedConstantsEnumerationsArraysStringsStructsUnionsTypedefsPointersDynamic Memory AllocationMallocCallocReallocFreeFunctionsFunction DeclarationsFunction DefinitionsFunction CallsReturn StatementInline FunctionsRecursionHeader FilesPreprocessor DirectivesControl FlowIf StatementElse StatementElse If StatementSwitch StatementCase StatementDefault CaseLoopsFor LoopWhile LoopDo While LoopBreak StatementContinue StatementGoto StatementLabelsOperatorsArithmetic OperatorsRelational OperatorsLogical OperatorsBitwise OperatorsAssignment OperatorsConditional (ternary) OperatorComma OperatorSizeof OperatorData StructuresLinked ListsStacksQueuesTreesGraphsFunction PointersCallbacksMacrosCommentsSingle Line CommentsMulti Line CommentsSyntaxSyntax ErrorsCompilation ErrorsDebuggingStandard Input OutputPrintfScanfFile HandlingFopenFcloseFreadFwriteFprintfFgetsFputsError HandlingErrnoAssertionsExit FunctionExit CodesEvent HandlingSignal HandlingInterrupts