La fonction signal en c

En C, la fonction signal() est utilisée pour gérer les signaux, qui sont des notifications asynchrones envoyées à un processus par le système d’exploitation ou par un autre processus. Elle permet de définir un gestionnaire de signal (une fonction de rappel) qui sera exécuté lorsque le processus reçoit un signal spécifique.

Prototype de signal()

#include <signal.h>
void (*signal(int sig, void (*handler)(int)))(int);
  • sig : Le numéro du signal à intercepter (ex: SIGINTSIGSEGV).
  • handler : Un pointeur vers la fonction de gestion du signal.

Valeurs de retour

  • En cas de succès, signal() renvoie l’ancien gestionnaire.
  • En cas d’échec, elle renvoie SIG_ERR et définit errno.

Le cas de SIGINT

SIGINT est provoqué par une interruption ctrl c

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

/* Fonction de gestion du signal SIGINT */
void sigint_handler(int sig) {
    (void)sig;  /* Évite un avertissement "unused parameter" */
    write(STDOUT_FILENO, "\nSignal SIGINT intercepté (Ctrl+C)\n", 34);
    exit(EXIT_SUCCESS);  /* Macro EXIT_SUCCESS de stdlib.h */
}

int main(void) {
    /* Configuration du gestionnaire de signal */
    if (signal(SIGINT, sigint_handler) == SIG_ERR) {
        perror("Erreur lors de la configuration du gestionnaire de signal");
        exit(EXIT_FAILURE);  /* Macro EXIT_FAILURE de stdlib.h */
    }

    printf("Le programme est en cours d'exécution...\n");
    printf("Appuyez sur Ctrl+C pour déclencher SIGINT.\n");

    /* Boucle infinie pour garder le programme actif */
    while (1) {
        sleep(1);
    }

    return EXIT_SUCCESS;  /* Macro EXIT_SUCCESS de stdlib.h */
}

Compilation:

gcc -std=c89 -ansi -pedantic -Wall -Wextra sigint_example.c -o sigint_example

vous pouvez tester directement le code

Avec gdb

gcc -g -std=c89 -ansi -pedantic -Wall -Wextra sigint_example.c -o sigint_example

Dans gdb il faudra désactiver gdb à la réaction de SIGINT pour utiliser notre programme.

la commande pour ,ne pas stopper gdb , ne pas afficher par gdb, et passer

handle SIGINT nostop noprint pass

signal avec kill

kill -SIGINT PID

ou

kill -2 PID

Ignorer un signal avec SIG_IGN

exemple :

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int main() {
    // Ignorer SIGINT (Ctrl+C n'aura plus d'effet)
    signal(SIGINT, SIG_IGN);

    printf("Essayez Ctrl+C, cela ne fera rien...\n");
    while (1) {
        sleep(1);
    }

    return 0;
}

Rétablir le comportement par défaut avec SIG_DFL

Exemple pour rétablir

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int main() {
    // Rétablir le comportement par défaut de SIGINT
    signal(SIGINT, SIG_DFL);

    printf("Ctrl+C terminera le processus.\n");
    while (1) {
        sleep(1);
    }

    return 0;
}

Signaux courants en C

SignalDescriptionDéclenchement classique
SIGINTInterruption (Ctrl+C)kill -2 ou Ctrl+C
SIGTERMDemande de terminaisonkill -15 (par défaut)
SIGKILLTerminaison forcée (ne peut être capturé)kill -9
SIGSEGVErreur de segmentationAccès mémoire invalide
SIGALRMAlarme (utilisé avec alarm())Timer expiré