Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Fonction signal

La fonction raise


Entête à inclure

#include <signal.h>  // <csignal> en C++

Fonction signal

typedef void (*handler)(int);
__sighandler_t signal( int signalId, __sighandler_t handler );

Un signal est un message émit à destination d'un processus (ou d'un groupe de processus) pour l'informer que quelque chose vient de survenir ou pour lui demander de réaliser une tâche particulière. La fonction signal permet de définir le gestionnaire de signal à invoquer en cas de réception d'un signal particulier.

La librairie C ISO spécifie les signaux suivants

Nom du signal Signification Description
SIGABRT Signal Abort Terminaison anormale, normalement initiée par la fonction abort
SIGFPE Signal Floating-Point Exception Opération arithmétique erronée, telle que division du zéro ou opération entraînant un dépassement de capacité. Attention, ce signal peut aussi déclencher suite à des manipulation de valeur numérique sans virgule flottante.
SIGILL Signal Illegal Instruction Exécution d'une instruction non conforme. Cela est généralement dû à une corruption du code ou à une tentative d'exécution de données.
SIGINT Signal Interrupt Un signal d'interruption généralement généré par l'utilisateur de l'application.
SIGSEGV Signal Segmentation Violation Accès à un segment de mémoire virtuelle non mappé en mémoire physique ou tentative de modification d'un segment de mémoire configuré en lecture seule.
SIGTERM Signal Terminate Signal de demande de terminaison du programme.

En complément chaque système d'exploitation compatible POSIX peut définir ses propres signaux.

Sous système Unix/Linux, vous pouvez obtenir la liste des signaux supportés par votre système d'exploitation en invoquant la commande suivante.
$> kill -l

Une fonction de traitement correspondant à un gestionnaire de signal doit respecter la signature suivante : void handler( int sigId );. Deux possibilités prédéfinies vous sont aussi proposées via les constantes suivantes :

vous ne pouvez pas intercepter tous les signaux. Par exemple, il est impossible d'intercepter le signal SIGKILL.
si vous interceptez le signal SIGTERM et que nous ne demandez pas explicitement une sortie du processus (via la fonction exit, par exemple), la sortie du processus initiée sera alors annulée !

Paramètres

Valeur de retour

Si le nouveau gestionnaire de signal est correctement configuré, la fonction signal vous renvoie l'ancien gestionnaire configuré pour ce signal. Si le gestionnaire n'a pas pu être changé, la constante SIG_ERR sera retournée.

Exemple de code

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void sigCont( int code ) {
    printf( ">>> SIGCONT received [%d]\n", code );
}

void sigTerm( int code ) {
    fprintf( stderr, ">>> SIGTERM received [%d]\n", code );
    
    // Pour forcer les appels sur les fonctions enregistrées par atexit
    exit( EXIT_SUCCESS );      
}

void exitFunction() {
    printf( "Exiting...\n" );
}

int main(void) {

    // On enregistre des fonctions à exécuter en cas de sortie normale du processus.
    atexit( exitFunction );

    // On enregistre quelques gestionnaires de signaux.
    signal( SIGTERM, &sigTerm );
    signal( SIGCONT, &sigCont );

    // Un message d'accueil.
    printf( "Welcome to SignalTest V1.0 :-)\n" );
    char buffer[100];

    // La boucle principale de notre console.
    while( true ) {
        printf( "Enter a command: " );
        fflush( stdout );
        scanf( "%s", buffer );

        if ( strcmp( buffer, "exit" ) == 0 ) break;
        if ( strcmp( buffer, "help" ) == 0 ) {
            // Affiche la liste des signaux supportés par le système.
            // Attention : ne marche que sur Linux/Unix !!!
            system( "bash -c \"kill -l\"" );
            continue;
        }

        int signalId = atoi( buffer );
        raise( signalId );              // C ISO 
        //kill( getpid(), signalId );   // POSIX (requière <unistd.h>)
    }

    return EXIT_SUCCESS;
}
Exemple d'utilisation de la fonction abort

Et voici le résultat produit par cet exemple.

$> gcc -o sample sample.c
$> ./sample
Welcome to SignalTest V1.0 :-)
Enter a command: help
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX    
Enter a command: 15
>>> SIGTERM received [15]
Exiting...
$>

Sujets connexes

<raise>
atexit
exit


La fonction raise