When dealing with POSIX signals, you have two means at your disposal. First, the easy (but discouraged) way, signal(). Second, the more elegant, current but complex way, sigaction(). Please use sigaction() unless you find that it isn't available on some platform that you need to work on.

This chapter of the glibc manual explains differences between the two and gives good example code on how to use both. It also lists the signals that can be handled, recommends how they should be handled and goes more in depth on how to tell how any given signal is (or is not) currently being handled. That's way more code than I'd want to paste into an answer here, hence the links.

It really is worth the hour or two it would take you to read the links and work through the examples. Signal handling (especially in programs that daemonize) is extremely important. A good program should handle all fatal signals that can be handled (i.e. SIGHUP) and explicitly ignore signals that it might not be using (i.e. SIGUSR1 / SIGUSR2).

It also won't hurt to study the difference between normal and real time signals, at least up to the understanding of how the kernel merges the prior and not the latter.

Once you work through it, you'll probably feel inclined to write up an easy to modify set of functions to handle your signals and re-use that code over and over again.

Sorry for not giving a quick and dirty code snippet to show you how to solve your immediate need, but this isn't a quick and dirty topic :)

Answer from user50049 on Stack Overflow
🌐
Linux Man Pages
man7.org › linux › man-pages › man2 › signal.2.html
signal(2) - Linux manual page
C89, POSIX.1-2001. In the original UNIX systems, when a handler that was established using signal() was invoked by the delivery of a signal, the disposition of the signal would be reset to SIG_DFL, and the system did not block delivery of further instances of the signal.
🌐
GeeksforGeeks
geeksforgeeks.org › c language › signals-c-language
Signals in C language - GeeksforGeeks
April 13, 2026 - A signal is a software-generated interrupt sent to a process by the OS when the user presses Ctrl-C or another process sends a signal to this process. There is a fixed set of signals that can be sent to a process.
Top answer
1 of 5
37

When dealing with POSIX signals, you have two means at your disposal. First, the easy (but discouraged) way, signal(). Second, the more elegant, current but complex way, sigaction(). Please use sigaction() unless you find that it isn't available on some platform that you need to work on.

This chapter of the glibc manual explains differences between the two and gives good example code on how to use both. It also lists the signals that can be handled, recommends how they should be handled and goes more in depth on how to tell how any given signal is (or is not) currently being handled. That's way more code than I'd want to paste into an answer here, hence the links.

It really is worth the hour or two it would take you to read the links and work through the examples. Signal handling (especially in programs that daemonize) is extremely important. A good program should handle all fatal signals that can be handled (i.e. SIGHUP) and explicitly ignore signals that it might not be using (i.e. SIGUSR1 / SIGUSR2).

It also won't hurt to study the difference between normal and real time signals, at least up to the understanding of how the kernel merges the prior and not the latter.

Once you work through it, you'll probably feel inclined to write up an easy to modify set of functions to handle your signals and re-use that code over and over again.

Sorry for not giving a quick and dirty code snippet to show you how to solve your immediate need, but this isn't a quick and dirty topic :)

2 of 5
16

Firstly, Ctrl+D is an EOF indicator which you cannot trap, when a program is waiting for input, hitting Ctrl+D signifies end of file and to expect no more input. On the other hand, using Ctrl+C to terminate a program - that is SIGINT, which can be trapped by doing this:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>

static void signal_handler(int);
static void cleanup(void);
void init_signals(void);
void panic(const char *, ...);

struct sigaction sigact;
char *progname;

int main(int argc, char **argv){
    char *s;
    progname = *(argv);
    atexit(cleanup);
    init_signals();
    // do the work
    exit(0);
}

void init_signals(void){
    sigact.sa_handler = signal_handler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIGINT, &sigact, (struct sigaction *)NULL);
}

static void signal_handler(int sig){
    if (sig == SIGINT) panic("Caught signal for Ctrl+C\n");
}

void panic(const char *fmt, ...){
    char buf[50];
    va_list argptr;
    va_start(argptr, fmt);
    vsprintf(buf, fmt, argptr);
    va_end(argptr);
    fprintf(stderr, buf);
    exit(-1);
}

void cleanup(void){
    sigemptyset(&sigact.sa_mask);
    /* Do any cleaning up chores here */
}
🌐
GitHub
github.com › torvalds › linux › blob › master › kernel › signal.c
linux/kernel/signal.c at master · torvalds/linux
* linux/kernel/signal.c · * * Copyright (C) 1991, 1992 Linus Torvalds · * * 1997-11-02 Modified for POSIX.1b signals by Richard Henderson · * * 2003-06-02 Jim Houston - Concurrent Computer Corp. * Changes to use preallocated sigqueue structures ·
Author   torvalds
🌐
The Open Group
pubs.opengroup.org › onlinepubs › 009604499 › functions › signal.html
signal
If and when the function returns, if the value of sig was SIGFPE, SIGILL, or SIGSEGV or any other implementation-defined value corresponding to a computational exception, the behavior is undefined. Otherwise, the program shall resume execution at the point it was interrupted. If the signal occurs as the result of calling the abort(), raise(), [CX] kill(), pthread_kill(), or sigqueue() function, the signal handler shall not call the raise() function.
🌐
Microsoft Learn
learn.microsoft.com › en-us › cpp › c-runtime-library › reference › signal
signal | Microsoft Learn
For more information about return codes, see errno, _doserrno, _sys_errlist, and _sys_nerr. The signal function enables a process to choose one of several ways to handle an interrupt signal from the operating system.
🌐
cppreference.com
en.cppreference.com › c › program › signal
signal - cppreference.com
When signal handler is set to a function and a signal occurs, it is implementation defined whether signal(sig, SIG_DFL) will be executed immediately before the start of signal handler. Also, the implementation can prevent some implementation-defined set of signals from occurring while the signal ...
Find elsewhere
🌐
TutorialsPoint
tutorialspoint.com › c_standard_library › c_function_signal.htm
C library - signal() function
The C library signal() function allows user to handle asynchronous event during the program execution. A asynchronous event refer to software notification which reports the events outside the program.
🌐
Chromium
chromium.org › chromium-os › developer-library › reference › linux-constants › signals
Linux Signal Table
For more details on signals in general, see the signal(7) man page. The SIGRTMIN & SIGRTMAX values listed below are technically dynamic. Implementations (e.g. glibc) are allowed to reserve things internally from the user's program. The constants listed below reflect the most common scenarios ...
🌐
Cppreference
cppreference.com › cpp › utility › program › signal
std::signal - cppreference.com
Signal handlers are expected to have C linkage and, in general, only use the features from the common subset of C and C++. However, common implementations allow a function with C++ linkage to be used as a signal handler.
🌐
Northern Illinois University
faculty.cs.niu.edu › ~hutchins › csci480 › signals.htm
LINUX Signals
An example of the use of signals is the use of the waitpid() function. It puts the calling process in a wait state (action = STOP) until the child process indicated has a change of status, which will be reported by a SIGCHILD signal (action = resume).
🌐
Wikipedia
en.wikipedia.org › wiki › C_signal_handling
C signal handling - Wikipedia
February 23, 2026 - In the C Standard Library, signal processing defines how a program handles various signals while it executes. A signal can report some exceptional behavior within the program (such as division by zero), or a signal can report some asynchronous event outside the program (such as someone striking ...
🌐
University of Kent
cs.kent.edu › ~ruttan › sysprog › lectures › signals.html
Introduction To Unix Signals Programming
Each signal may have a signal handler, which is a function that gets called when the process receives that signal. The function is called in "asynchronous mode", meaning that no where in your program you have code that calls this function directly. Instead, when the signal is sent to the process, the operating system stops the execution of the process, and "forces" it to call the signal handler function.
🌐
The Open Group
pubs.opengroup.org › onlinepubs › 009695399 › basedefs › signal.h.html
<signal.h>
It is implementation-defined whether realtime signal behavior is supported for other signals. This header also declares the constants that are used to refer to the signals that occur in the system. Signals defined here begin with the letters SIG. Each of the signals have distinct positive integer values.
🌐
Medium
medium.com › @rikis1 › signals-ad83f38f80b6
Understanding Signals in the C Language: Harness the Power of Asynchronous Event Handling | by RB | Medium
July 4, 2023 - A signal in C is a software interrupt or notification that enables processes to handle nonynchronous events, facilitate inter-process communication, and respond to exceptional situations during program execution.
🌐
O'Reilly
oreilly.com › library › view › c-in-a › 0596006977 › re206.html
signal - C in a Nutshell [Book]
December 16, 2005 - If the handler argument is a function pointer, then signal() installs this function as the routine to be called the next time the program receives the signal designated by the integer parameter sig.
Authors   Peter PrinzTony Crawford
Published   2005
Pages   618
🌐
CodeSignal
codesignal.com › home
CodeSignal | The AI-Native Skills Platform
November 18, 2022 - Tailored to your roles, seniority, and context. Pick an agent, or create your own, and get signal fast.
🌐
Illinois
cs341.cs.illinois.edu › coursebook › Signals
CS 341 · Signals
Signals are a convenient way to deliver low-priority information and for users to interact with their programs when other ways don’t work (for example standard input being frozen). They allow a program to clean up or perform an action in the case of an event.
🌐
Code Quoi
codequoi.com › en › sending-and-intercepting-a-signal-in-c
Sending and Intercepting a Signal in C - codequoi
November 11, 2022 - It is asynchronously sent to a running program to notify it of some event. The system interrupts the process’ normal execution to trigger a specific reaction like, among other things, terminating it. So signals are a sort of inter-process communication.