CSC 3102 – Introduction aux systèmes d’exploitation

Portail informatique

Contrôle Final 1 – Année 2016/2017

Le barème est donné à titre indicatif

Pour faire les exercices, vous avez besoin de connaître le langage bash. Vous pouvez vous référer à l'annexe shell que vous pouvez trouver ici.

Pour faire le contrôle, vous aurez aussi besoin des scripts et .

On vous rappelle que vous devez exécuter vos scripts pour les tester. Si les scripts ne peuvent pas s'exécuter, vous perdrez des points.

Préparation (2 points, ∼5mn)

Créez un répertoire Nom_Prenom, où Nom est votre nom et Prenom votre prénom. Dans ce répertoire, vous devez créer des sous répertoires nommés exo2 et exo3 dans lesquels vous mettrez les scripts des différents exercices.

À la fin du contrôle, vous devez rendre une archive contenant exactement cette arborescence. On vous rappelle que vous pouvez créer une archive de la façon suivante :
$ tar -f Nom_Prenom.tgz -cz Nom_Prenom

Un petit serveur de messagerie (11 points, ∼40mn)

Cet exercice évalue vos connaissances sur les redirections, les tubes nommés, les signaux et les synchronisations.

Pour vous guider, le script de notre corrigé type fait 14 lignes (sans compter les lignes blanches ou les lignes de commentaires). Si vous voyez que vous écrivez largement plus de lignes, dîtes vous que vous êtes sur une mauvaise piste.
Le but de cet exercice est de concevoir un petit serveur de messagerie, c'est-à-dire un serveur permettant d'envoyer des messages à des utilisateurs. Ce serveur doit créer un tube et attendre des requêtes pour gérer les messages. Les requêtes sont composées de mots sur une unique ligne. Une requête commence par un type :
  • send est utilisé pour poster un message. Pour ce type de requête, le second mot est le nom de l'utilisateur destinataire du message, et les mots suivants constituent le message.
  • recv est utilisé pour recevoir les messages d'un utilisateur. Pour ce type de requête, le second mot est le nom de l'utilisateur qui souhaite consulter ses messages.

(4 point)

Écrivez un script nommé mail-server.sh qui :
  • crée un tube nommé tube-server,
  • ouvre le tube en lecture-écriture,
  • et exécute une boucle infinie (while true; do ... done) dans laquelle le serveur lit les lignes reçues dans le tube. Lors de la lecture d'une requête, vous veillerez à stocker :
    • le type de la requête dans une variable nommée type,
    • l'utilisateur associé à la requête dans une variable nommée id,
    • la fin de la requête dans une variable nommée msg.

(2 point)

Modifiez le script mail-server.sh de façon à traiter les requêtes de type send. Lors de la réception d'un message de type send, le serveur doit enregistrer le contenu du message dans le fichier nommé id.

Vous pouvez effectuer des tests en lançant votre serveur dans un terminal, et en exécutant, par exemple, la séquence de commandes suivantes dans un autre terminal :
$ echo send Luke Je suis ton père >tube-server $ cat Luke Je suis ton père $ echo send Luke En fait, non >tube-server $ cat Luke Je suis ton père En fait, non $

2 points

Modifiez le script mail-server.sh de façon traiter les requêtes de type recv. Lors de la réception d'un recv, le serveur doit :
  • afficher les messages reçus par id (et qui sont stockés dans le fichier id) sur la sortie standard du serveur,
  • puis supprimer le fichier id.

Comme à la question précédente, vous pouvez tester votre serveur en le lançant dans un terminal, puis en écrivant directement la requête recv Luke dans le tube tube-server dans un autre terminal. Tel que l'exercice est posé, il est normal que les messages reçus par Luke s'affichent dans le terminal du serveur.

3 points

On souhaite maintenant pouvoir gérer en parallèle plusieurs requêtes. Vous veillerez à identifier les sections critiques et à en protéger l'accès avec des mutexes. De façon à lancer les commandes associées aux requêtes en tâche de fond., pensez que vous pouvez lancer n'importe quel regroupement de commandes en tâche de fond. Par exemple, if ... fi &, case ... esac &, ou ( ... ) & lancent l'ensemble des regroupements en tâche de fond.

1 point, bonus

Modifiez le script mail-server.sh de façon à ce que, lors de la réception d'un signal SIGINT, le serveur détruise le tube mail-server.sh avant de quitter.

Le plus gros fichier (7 points, ∼30mn)

Cet exercice évalue vos connaissances sur les tubes anonymes, les fichiers et les commandes de base.

Pour vous guider, le script de notre corrigé type fait 21 lignes (sans compter les lignes blanches ou les lignes de commentaires). Si vous voyez que vous écrivez largement plus de lignes, dîtes vous que vous êtes sur une mauvaise piste.

On souhaite écrire un script max_size.sh qui prend un fichier en argument. Un appel possible est :

./max_size.sh dir

Le but de ce script est d'afficher le nom et la taille du plus gros fichier parmi tous les fichiers du répertoire dir.

6 points

On souhaite dans un premier temps écrire un script qui ne considère que les fichiers situés dans le répertoire dir passé en paramètre, sans considérer les fichiers situés dans des sous-répertoires de dir.

Si le paramètre dir n'est pas donné ou si dir n'est pas un répertoire, le script doit se terminer en affichant un message d'erreur.

Une exécution possible est :

$ ./max_size.sh Usage: ./max_size.sh DIRECTORY $ ./max_size.sh toto.txt toto.txt n'est pas un répertoire ! $ ./max_size.sh /usr/include/ max: /usr/include/bfd.h (size: 255297)

Écrivez le script max_size.sh qui:

  • Vérifie que le nombre de paramètre est correct
  • Vérifie que le paramètre dir est bien un répertoire
  • Parcourt les fichiers du répertoire dir et
    • calcule la taille de chaque fichier
    • trouve la taille maximale
  • Affiche le nom et la taille du plus gros fichier trouvé

(1 point)

Ajouter en commentaire à la fin du fichier max_size.sh la commande permettant de rendre le script max_size.sh exécutable pour l'utilisateur et le groupe de l'utilisateur. On vous rappelle qu'un commentaire en shell est indiqué par le caractère « # ».

(1 point, bonus)

On souhaite maintenant que max_size.sh dir trouve le plus gros fichier parmi tous les fichiers du répertoire dir ainsi que les fichiers situés dans des sous-répertoires de dir.

Faites une copie du fichier max_size.sh et appelez la max_size_recursive.sh. Modifiez le script max_size_recursive.sh pour qu'il cherche le plus gros fichier parmi les sous-répertoires du répertoire passé en paramètre.

Une exécution possible est :
$ ./max_size_recursive.sh 2015-2016 max: 2015-2016/cf2/2015-2016_CF2_sujet1_correction.pdf (size: 87105)