Test n° 1 de système

(7 décembre 2001 – durée : 2h)

 © D. Mathieu   mathieu@romarin.univ-aix.fr  et M. Laporte
I.U.T.d'Aix en Provence - Département Informatique
Créé le 01/12/2001 - Dernière mise à jour : 01/12/2001

Tout document autorisé

Sommaire

Sauvegarde/Restauration des signaux
Fichier SaveSig.cxx

I - Sauvegarde/Restauration des signaux

    La fonction SaveSig(), écrite lors du TP consacré aux signaux sous Unix, déroute l'ensemble des signaux déroutables vers un traitant unique, en sauvegardant l'ancien traitant. La fonction Restaure()  déroute l'ensemble des signaux déroutables vers l'ancien traitant, sous réserve qu'il ait été préalablement sauvegardé par SaveSig().

    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 ();               // ---

Fichier SaveSig.cxx

    L'objectif de cet exercice est de réécrire complètement les deux fonctions pour prendre en compte la totalité des remarques ci-dessus. Afin de vous aider, voici quelques indications à suivre :

[1] La fonction système sigprocmask() est elle aussi interruptible par un signal..

[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.

[4] man sigaction :
 
SYNOPSIS
  #include <signal.h>

  int sigaction (int signum, 
                 const struct sigaction *act,
                 struct sigaction *oldact);
...
ERREURS
  EINVAL Un  signal invalide est indique. 
         Ceci se produit également si l'on tente de modifier
         l'action associée à SIGKILL ou SIGSTOP.

  EFAULT act, oldact pointent en-dehors de l'espace d'adressage accessible.

  EINTR  L'appel système a été interrompu.


Corrigé : SaveSig.cxx

© D. Mathieu    mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique