Fichier SaveSig.cxx
L'écriture en est assez lourde, parce que la fonction système sigaction() est interruptible par les signaux [1]. Une solution plus élégante serait de suspendre (bloquer) tous les signaux possibles le temps de l'opération.
De plus, il est souhaitable de disposer de fonctions
équivalentes pour sauvegarder/restaurer un seul signal, dont
les profils seraient :
void SaveSig (const sighandler_t
Handler,
int NumSig = 0) [2] [3] throw CExcFct); void RestaureSig (int NumSig = 0) throw CExcFct); |
Lorsque le paramètre NumSig est nul, ce sont tous les signaux déroutables qui sont déroutés. Sinon, c'est seulement celui dont la valeur est passée en paramètre qui est dérouté (s'il est déroutable). Idem pour la fonction Restaure().
Conformément aux spécifications indiquées
dans la version faite en TP, on n'envisagera pas d'imbriquer des blocs
de sauvegarde générale. Ainsi, l'écriture suivante
ne sera pas acceptée :
SaveSig (Handler1);
// -------
... // | SaveSig (Handler2); // --- | ... // | | RestaureSig (); // --- | ... // | RestaureSig (); // ------- |
De même, on n'envisagera pas d'imbriquer des
sauvegardes individuelles du même signal. Ainsi, l'écriture
suivante sera interdite :
SaveSig (Handler1, SIGUSR1); // -------
... // | SaveSig (Handler2, SIGUSR1); // --- | ... // | | RestaureSig (SIGUSR1); // --- | ... // | RestaureSig (SIGUSR1); // ------- |
Cependant, on devra pouvoir imbriquer chacune des
structures :
SaveSig (Handler1);
// -------
... // | SaveSig (Handler2, SIGUSR1); // --- | ... // | | RestaureSig (SIGUSR1); // --- | ... // | RestaureSig (); // ------- |
ou
SaveSig (Handler2, SIGUSR1); // -------
... // | SaveSig (Handler1); // --- | ... // | | RestaureSig (); // --- | ... // | RestaureSig (SIGUSR1); // ------- |
Il sera de la responsabilité de ces fonctions
de s'en assurer. En revanche, on laissera à l'utilisateur le soin
de vérifier que les deux structures ne sont pas entrelacées
:
SaveSig (Handler2, SIGUSR1); // -------
... // | SaveSig (Handler1); // --- | ... // | | RestaureSig (SIGUSR1); // ---+--- ... // | RestaureSig (); // --- |
void BlockAllSig (const sigset_t &
Masque) ...
{ } // BlockAllSig() |
qui boque tous les signaux bloquables,
void SauverUnSignal (const sighandler_t
NewHandler, int NumSig,
struct std::sigaction & OldAction) ... { } // SauverUnSignal() |
On suppose qu'elle ne sera appelée que :
Le paramètre OldAction contient en sortie l'ancien
traitant du signal.
Compléter le profil (exception) et le corps de la fonction :
voir un extrait de man sigaction [4]
comprenant la liste exhaustive des erreurs. On rappelle que, dans
les spécifications de SaveSig(), on s'interdit de dérouter
des signaux qui seraient déjà ignorés.
void RestaurerUnSignal (int NumSig,
const struct std::sigaction & OldAction) ... { } // RestaurerUnSignal() |
On suppose qu'elle ne sera appelée que :
Le paramètre OldAction contient l'ancien traitant
du signal, à restaurer.
[2] L'utilisation d'un paramètre supplémentaire ayant une valeur par défaut n'oblige pas les utilisateurs à modifier leur code déjà écrit.
[3] la valeur nulle ne correspond à aucun signal.
SYNOPSIS
#include <signal.h> int sigaction (int signum,
EFAULT act, oldact pointent en-dehors de l'espace d'adressage accessible. EINTR L'appel système a été interrompu. |
© D. Mathieu mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique