Programmation C source/gestion des signaux
Apparence
#include <stdio.h>
#include <signal.h>
int main(void)
{
printf("----------------------------------------\n");
printf(" Gestion des signaux\n");
printf("----------------------------------------\n");
/*
Les signaux permettent une communication, assez sommaire, entre le système et un
processus, ou entre différents processus. Un signal ne porte qu'une seule
information: son numéro, de type int. Un processus peut s'envoyer un signal à
lui-même. Ces signaux sont envoyés de manière asynchrone: lorsqu'un processus
reçoit un signal, son exécution est interrompue, et une fonction spécifique, dite
gestionnaire de signal, est appelée, avec en paramètre le numéro du signal reçu,
pour traiter l'événement. Lorsque cette fonction se termine, le processus reprend
là où il s'était arrêté. C'est à chaque processus de déterminer ce qu'il fait
quand il reçoit un signal de numéro donné, en définissant un gestionnaire de
signal pour tous les signaux qu'il le souhaite. En l'absence de précisions dans
nos programmes, l'implémentation fournira en effet un gestionnaire de signal par
défaut, qui le plus souvent se contentera d'arrêter le programme.
*/
#if 0
#include <signal.h>
signal() // pour définir un gestionnaire de signal
raise() // pour envoyer un signal au processus courant
#endif
/*
Le C définit ces deux fonctions, et pas plus.
On retrouve donc signal() et raise() sur tous les sytèmes d'exploitation
qui propose le langage C; mais pour d'autres fonctions, elles sont propres
à tel ou tel système. Par exemple nous avons les fonctions de gestion de
signaux, définies par la norme POSIX, pour les systèmes qui ont choisi de
respecter la norme POSIX.
*/
#if 0
void (* signal( int sig, void (*func)(int) ) )(int);
typedef void (*handler_t)(int);
handler_t signal(int sig, handler_t func);
#endif
/*
les paramètres :
sig numéro de signal
func pointeur vers la fonction de gestion du signal
pour sig : dans signal.h
nous avons un certain nombre de signaux définit par des macros
par exemple SIGSEGV qui indique un accès illégal à la mémoire (SEGmentation
Violation)
pour func : dans signal.h, nous avons
SIG_IGN le signal sera ignoré
SIG_DFL le gestionnaire de signal par défaut sera mis en place
sinon bien sur il faut donner une fonction que nous avons écrite !
retour de signal() :
En cas d'erreur, la fonction renvoie SIG_ERR et place la variable errno à une
valeur significative.
Exemple :
avec le signal SIGFPE, qui normalement est là pour indiquer une exception
lors des calculs en virgule flottante (Floating Point Exception)
*/
void sig_fpe(int sig)
{
// grace au paramètre sig, cette fonction pourrait traiter différents signaux
if (sig == SIGFPE)
puts("le signal SIGFPE a été reçu, execution de sig_fpe()");
else
puts("sig_fpe() : signal reçu inconnu !");
}
if (signal(SIGFPE, sig_fpe) == SIG_ERR)
{
puts("Le gestionnaire de signal pour SIGFPE n'a pu etre defini.");
}
else
{
puts("Le gestionnaire de signal pour SIGFPE a pu etre defini.");
}
raise(SIGFPE);
while(1);
return 0;
}