Examen de Systèmes II -- Licence -- Septembre 2004

Exercice

Écrire un programme permettant d'exécuter en séquence une suite de programmes donnés en paramètres et qui s'arrête à la première commande qui échoue. Le code de retour de cette commande sera le code de la dernière commande exécutée. Le prototype de la commande est: sequence c1 c2 c3 c4 ... c$_n$

Exercice

Écrire un programme permettant d'exécuter en parallèle un ensemble de programmes donnés en paramètres et qui s'arrête à la terminaison du dernier, le code de retour de la commande signalera un échec si et seulement si l'une des commandes termine en échec. Le prototype de la commande est: parallele c1 c2 ... c$_n$.

Exercice

Soit les deux programmes suivant:
/* Programme 1 */
int main(int argc,char *argv[]) {
  if (fork()==0) main(argc,argv);
}
/* Programme 2 */
int main(int argc,char *argv[]) {
  if (fork()==0) execvp(argv[0],argv);
}
Décrivez le comportement de chacun des programmes (en termes de processus, parenté, terminaison, etc).

Exercice

  1. Écrire un programme permettant de compter le nombre d'occurrence de chaque signal reçu pendant son exécution. L'exécution devra s'arrêter lorsque le processus aura reçu (en tout) $N$ (constante) signaux.
  2. Combien de signaux auront été envoyés au processus pendant son exécution ?

Exercice

  1. Écrire un programme permettant d'exécuter $n_f$ fils. Chaque fils se chargera de capturer le signal SIGUSR1 et à sa réception devra incrémenter une variable partagée avec tous les autres (père et frères) et compter le nombre d'occurrences reçues qui lui sont propres. Lorsqu'un fils aura reçu $n_s$ occurrences il devra se terminer. Le processus père se terminera lorsque tous ses fils se termineront.
  2. Est-il possible de garantir que le père se termine si l'on envoie à chaque fils $n_s$ SIGUSR1 assez espacés dans le temps? Si oui, comment? Si non, pourquoi ?

Problème

On vous demande d'écrire un ensemble de fonctions permettant d'implanter un système de messagerie dans lequel il est possible de déposer des messages (de taille fixe $T$ et en nombre au plus égal à $N$) et de les retirer à volonté.
  1. quel(le)s constructions/concepts (sauf les files de messages!) Unix allez-vous utiliser ? Justifiez.
  2. Comment allez-vous les utiliser ?
  3. Écrire la fonction permettant d'ouvrir la messagerie et dont le prototype est:
    FileDeMessage *openFileDeMessage(char *nomDeLaFile,int mode);
    Si le mode ``contient'' la valeur NEW, une nouvelle file sera créée si nécessaire. Si le mode ``contient'' la valeur READ, la file sera en plus ouverte en lecture et l'on pourra alors extraire des messages. Si le mode ``contient'' la valeur WRITE, la file sera ouverte en écriture permettant d'y déposer un nouveau message. En cas d'échec la fonction renverra NULL.
  4. Écrire la fonction d'extraction de message dont le prototype est:
    int readMessage(FileDeMessage *file,void *message,int mode);
    Si le mode vaut 0 l'extraction sera bloquante, et non bloquante sinon. En cas d'échec la fonction renverra une valeur négative.
  5. Écrire la fonction de dépôt de message de prototype:
    int writeMessage(FileDeMessage *file,void *message,int mode);
  6. Écrire la fonction de fermeture de la file dont le prototype est:
    int closeFileDeMessage(FileDeMessage *file);