#include <signal.h> // <csignal> en C++
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.
$> 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 :
SIG_DFL : la fonction par défaut à utiliser pour le signal considéré.
SIG_IGN : pour demander à ignorer le signal considéré.
SIGKILL
.
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 !
signalId : l'identifiant du signal à intercepter. Il est conseillé d'utiliser les constantes associées au signaux en lieu et place de leurs
valeurs numérique (Ex: SIGTERM
, SIGCONT
, ...).
handler : le pointeur sur la fonction à déclencher en cas de réception du signal spécifié en premier paramètre.
Ce paramètre peut aussi être fixé à SIG_DFL
ou SIG_IGN
.
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.
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; } |
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... $>
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 :