TP - Programmation répartie (M4102) UE 41

Les signaux.

 

Les signaux sont un ensemble de procédés implémenté par le système, permettant à celui-ci d'avertir un processus d'un évenement. Ce TP vise à vous familiariser avec ces signaux et leurs usages au travers de quelques exemples. Tous les signaux ne sont pas vus, ni certaines de leurs subtilités (les différents types de masquages par exemple). 

 

Exercice 1 : SIGINT et Ctrl-C.

  1. Vous devez écrire un programme simple qui affiche le message "Bonjour" toutes les secondes et qui ne s'arrête jamais (vous utiliserez sleep()).
  2. Vous devrez coder un handler qui devra afficher un message du type « Fin du programme » à la réception du signal SIGINT (généré par le système lorsque l'utilisateur appuie sur Contrôle-C). Le handler finira par un exit()
  3. Retirer l'instruction exit() du handler et testez.
  4. Masquer le signal SIGINT pendant 60 secondes puis libérez le. Testez en appuyant sur Ctrl-C durant ces 60 secondes.

 

Exercice 2 : Zombies et SIGCHLD

 

Afin de tester la gestion synchrone des zombies vous devez écrire le programme suivant:

1. Création de zombies:

  • création de deux fils
  • le fils 1 attend x secondes (avec sleep())
  • le fils 2 attend y secondes (avec sleep()) et y>x
  • le père une fois les deux fils créés boucle indéfiniment.

Observez les zombies avec la commande ps (ps aux).

 

2. Créez un handler qui intercèpte le signal SIGCHD (celui-ci est émis au moment de la terminaison d'un fils), gérez les processus zombies (avec waitpid()), puis affichez un message du type "Terminaison du fils de pid xxx". Vérifiez qu'il n'y a effectivement plus de zombies avec la commande ps.

 

Exercice 3 : Lecture d'un fichier de configuration à chaud (SIGHUP)

Vous allez coder une version extrêmement basique de votre mini-shell. Celui-ci lit un fichier de configuration au moment de son lancement. Ce fichier ne contient qu'une seule ligne qui correspond au prompt qui doit être affiché.  Le fichier de configuration pourra s’appeler shell.conf.

Ce que fait votre mini-shell:

  • Affichage du prompt sans retour à la ligne
  • Lecture de l'entrée standard (read(0,...))
  • Affichage de ce qui a été saisie sur l'entrée standard
  • retour à l'affichage du prompt

 

Afin de prendre en compte les modifications qui pourraient être apporté sur ce fichier alors que le mini-shell est en cours d’exécution, il vous faudra recharger ce fichier de configuration à chaque réception du signal SIGHUP. Vous testerez également le signal avec et sans l’option SA_RESTART.

Appels : sigaction(2).

Commandes pour tester : kill(2).

 

 

TP3 - Programmation système (M3101-1) SE TP UE3

Redirection, tâches de fond, et pipe.

 

 

Conseil préliminaire

Dans ce TP, on ne vous fournit pas de fichier Makefile. C'est à vous de l'écrire (voir avec votre enseignant pour un petit cours en début de séance).

 

Exercice 1 : redirection de la sortie standard

Un shell classique permet de rediriger les entrées/sorties standards vers d'autres fichiers, en utilisant les ca­ractères spéciaux < et >. Vous devez d'abord tester ces fonctionnalités dans votre shell (>, >>, 2>, 2>> et <). Ces fonctionnalités sont implementées au niveau du shell. Celui-ci recherche ces caractères spéciaux avant de lancer la commande. Il effectue la redirection et supprime ces caractères spéciaux (ainsi que ce qui est à leur droite) lors du passage des arguments à la commande. Cependant, notez que ces fonctionnalité n'ont pas besoin d'être interne au shell : elles peuvent être implantées avec une syntaxe différente, comme une commande externe.

On vous demande d'intégrer ces fonctionnalités à votre shell (TP 3).  Vous devrez tester avec une commande qui prenne au minimum deux arguments :

uneCommande unArgument > nomDeFichier

par exemple

  ls toto.txt > out.txt

Votre shell doit ouvrir en écriture le fichier dont le nom lui est passé après la redirection (out.txt dans l'exemple ci-dessus), et redirige sa propre sortie standard vers ce fichier, à l'aide de la fonction dup2(2) ou dup(2). Ensuite, il exécute la commande passée en première argument (ls dans l'exemple), en lui passant tous les arguments suivants le cas échéant (toto.txt dans l'exemple).

Notez que si le fichier n'existe pas (out.txt), il doit être créé ; s'il existe, son contenu doit être remplacé.

On notera que le paramètre argv de la fonction main respecte le format attendu par la fonction execvp(3) : il se termine par un pointeur NULL.

 

Exercice 2 : redirections généralisées¶

En partant du programme de l'exercice précédent, vuos devez prendre en compte les redirections suivantes:

  • >> redirection de la sortie standard en mode ajout
  • 2> redirection de la sortie erreur (vous pourrez tester avec ls fichierQuiNexistePas.txt)
  • 2>> redirection de la sortie erreur en mode ajout
  • < redirection de l'entrée standard (vous pourrez tester avec cat: cat < fichier.txt)

 

Exercice 3 : tâches de fond

Dans un shell classique, on peut lancer une commande en tâche de fond, en particulier lorsque l’on ne souhaite pas mono­poliser l’interpréteur pour cette commande, et que l’on veut pouvoir lancer d’autres commandes en parallèle. Pour cela, on fait suivre la ligne de commande d’un &.

 

Il s’agit maintenant de rajouter cette fonctionnalité à votre shell, basé sur le shell de l'exercice précédent ou celui du TP3 pour simplifier. Lorsque la ligne de commande saisie finit par & (tâche de fond), alors la commande sera lancée dans un nouveau processus (fonctionnement normal), mais votre shell n’attendra pas la fin de l’exécution et il ré­affichera immédiatement l'invite de saisie pour saisir et exécuter la commande suivante.

Lorsque la ligne de commande saisie ne finit pas par le caractère &, la commande correspondante sera exécutée, et votre programme attendra la fin de l’exécution pour ré­afficher l'invite de saisie (même com­portement que dans le TP3).

Attention encore à ne pas créer de zombies...

Vous ferez en sorte que, lorsqu’une commande lancée en tâche de fond se termine, votre shell affiche un message indiquant la fin du processus (avec son numéro de pid). Testez avec le shell (le vrai) pour voir le comportement attendu (avec "sleep 5 &" par exemple).

Exercice 4 : Tubes (pipes)

Vous devez apporter une dernière amélioration à votre shell: la gestion des tubes (pipes en anglais). Il s’agit de rediriger la sortie standard d’une première commande sur l’entrée standard d’une deuxième commande, mais pour que la communication puisse avoir lieu il vous faudra utiliser un tube entre ces deux entrées-sorties. Vous pourrez tester le bon fonctionnement de votre shell avec la commande:

                       monPrompt$ cat fichier | wc –l

L'appel système à utiliser est: pipe(2).

Metric ETX_ANT

 

We have implemented an extension to the olsr daemon olsrd. It integrates the use and computation of the classical routing metric ETX. It aims to be used in wireless ad hoc and mesh networks. The related article is:

Sabrine Naimi, Anthony Busson, Véronique Vèque, Larbi Ben Hadj Slama, Ridha Bouallegue:
Anticipation of ETX Metric to Manage Mobility in Ad Hoc Wireless Networks. ADHOC-NOW 2014: 29-42 [link]

 

The source code is available here as a zip file: code.zip

Note that the linux wireless tool iw has to be installed. It is called to obtain the signal strength for each neighbor. The compilation steps are the same as for the native olsrd daemon [link].

 

 

 

 

TP2 - Programmation système (M3101-1) SE TP UE31

Manipulation d'un fichier binaire et verrouillage

 

Exercice :

L'idée de l'exrecice est de vous faire manipuler un fichier binaire (non ASCII), lecture, écriture, déplacement, et d'introduire les notions de verrouillages de fichiers.

Vous devez télécharger le fichier lockfile.c. Celui-ci contient le squellete (main, nom des fonctions et arguments) permettant de gérer un répertoire de noms. Commencez par lire attentivement les commentaires qui précèdent chaque procédure/fonction afin de comprendre leur rôle.

  1. Modifiez/complétez les fonctions litUneEntree(), affichage(), affichageEntree().

  2. Modifiez/complétez les fonctions ajout() et modificationEntree().

  3. Modifiez les fonctions verrouillage et deverrouillage(). Vous devrez utiliser la fonction de la libc lockf(). Celles ci doivent être utilisées dans les fonctions ajout() et modificationEntree() de manière à garantir qu'il ne pourra pas y avoir d'accès concurrent en écriture sur les parties du fichier concernées. Vous testerez un verrouillage bloquant et un verrouillage non bloquant. Pour ce dernier, si un verrou est en cours, le programme devra afficher un message d'erreur et revenir au menu principal.

Question (vous devez répondre dans lockfileEmpty.c) :

1. Le verrouillage fonctionne-t-il pour des accès en lecture ?

2. Quelle est la différence entre les opérations F_TLOCK et F_TEST ?

 TP3 - Programmation système (M3101-1) SE TP UE31

Création de processus - variables d'environnement

 

 

Exercice 1 : un peu de généalogie

Examinez le programme mesForks.c (vieille version mes_fork.c). Essayez d'abord de deviner ce qu'il va afficher. Ensuite, compilez-le et exécutez-le.
Dans votre rapport, vous donnerez :

  • la sortie obtenue,
  • le nombre de processus créés par ce programme,
  • leur arbre généalogique (vous pourrez utiliser la commande pstree).

 

Exercice 2 : écriture d'un shell basique

Écrivez un programme shell1 implémentant les fonction basiques d'un interpréteur de commande (« shell »). Ce programme boucle sur les trois actions suivants :

  1. affichage d'un message d'invite,
  2. saisie d'une commande,
  3. exécution de la commande saisie,

jusqu'à ce que l'utilisateur saisisse le caractère fin de fichier (CTRL+D) ou la commande spéciale exit.

Remarques :

  • Votre programme devra créer un nouveau processus pour chaque commande à exécuter.
  • Votre programme ne devra pas créer de zombies...
  • Si la commande saisie n’existe pas, votre programme devra afficher un message d’erreur approprié.
  • Si la commande est vide (l’utilisateur a simplement tapé « entrée »), alors votre programme devra simplement ré­-afficher l'invite de saisie, sans afficher de message d’erreur.
  • Pour saisir une commande, et la découper en « mots », vous pouvez utiliser la fonction lis_ligne() ( ligne_commnde.c ligne_commande.h) spécifiée dans le fichier fournit ici.

Vous aurez besoin des appels systèmes fork(2), waitpid(2) et execvp(3).

 

Exercice 3 : gestion de l'environnement dans le shell

Rappel : Tout processus possède un _environnement_ : c'est une liste de variables possédant un nom (traditionnelle­ment en majuscules) et une valeur (chaîne de caractères). Cet environnement peut être affiché par la com­mande env. Comme toutes les propriétés d'un processus, l'environnement du processus père est copié pour chaque processus fils (c'est ainsi que la commande env permet d'afficher l'environnement du shell qui l'a lancé...).

Écrivez un programme shell2, basé sur celui de l'exercice précédent, pourvu d'une commande interne permettant de modifier sont environnement. Cette commande prendra la forme

    export NOM=valeur


NB: vous pourrez utiliser la fonction separe_egal spécifiée dans le fichier ligne_commande.h.

Par ailleurs, vous modifierez votre shell pour que, si la variable d'environnement INVITE est définie, c'est sa valeur qui sera affichée en guise d'invite.

Vous aurez besoin des appels systèmes getenv(3) et setenv(3).

Dans votre rapport, vous expliquerez pourquoi la commande export doit être implémentée comme une commande interne (c.à.d. à l'intérieur du shell) et non comme une commande externe (un programme lancé par le shell).