Examen de Systèmes II
Licence - Septembre 2001

Exercice

Soit le programme suivant :
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
  pid_t pid;

  printf("Salut, c'est ");
  if ( (pid = fork()) == 0 ) {
    printf("pas moi\n");
  } else {
    printf("lui\n");
  }
}
  1. quels sont les affichages possibles à l'exécution d'un tel programme ? Justifiez.
  2. quel mécanisme utiliseriez-vous pour garantir un ordre donné sur les messages ? Écrivez le code correspondant.

Exercice

Soit le programme test.c suivant :
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char *argv[]) {
  int ret, i, n, status;

  if (argc==1) exit(EXIT_SUCCESS);
  n = atoi(argv[argc-1]);
  for (i=0; i<n; i++) {
    switch(fork()) {
    case 0:
      argv[--argc] = NULL;
      execvp(argv[0],argv);
      exit(EXIT_FAILURE);
    case -1:
      exit(EXIT_FAILURE);
    default:
      break;
    }
  }
  ret = EXIT_SUCCESS;
  for (i=0; i<n; i++) {
    if (wait(&status)!=(pid_t)-1) {
      if (!(WIFEXITED(status) && WEXITSTATUS(status)==EXIT_SUCCESS))
        ret = EXIT_FAILURE;
    }
  }
  exit(ret);
}
  1. combien de processus sont-t'ils créés lors d'une exécution par test ? par test 3 ? par test 2 4 ? par test 2 1 5 ? pour chaque exécution dessinez l'arbre généalogique des processus.
  2. dans quel ordre les processus se terminent-ils ?
  3. si l'on supprime la seconde boucle for() et son contenu. Quelle différence cela fait-il ?
  4. et si l'on remplace la seconde boucle for() et son contenu par un simple appel à wait(NULL) ?

Exercice

Écrivez une commande réalisant un calcul quelconque (supposé long) obligeant l'utilisateur à frapper le caractère CTRL-C à intervalles ne dépassant pas 5 secondes, sinon le processus se terminera immédiatement en indiquant une erreur.

Exercice

  1. pour un shell, qu'est ce qu'une commande interne/externe ?
  2. quelles sont les commandes qui ne peuvent être qu'internes ? et pourquoi ?
  3. pourquoi certains shells proposent-ils en interne des commandes comme ls ?

Problème

On vous propose d'écrire un système de réservation. Les utilisateurs de ce système sont identifiés par leur uid, les objets à réserver sont identifiés par un entier (positif). Il ne doit pas être possible à un utilisateur de réserver plus d'un objet, et à un objet d'être réservé par deux utilisateurs.

La base de données prendra la forme de deux fichiers. Le premier (objets) contient des entiers identificateurs d'utilisateurs (0 pour indiquer qu'un objet est libre), et le second (utilisateurs) contient des entiers identificateurs d'objets (0 pour indiquer qu'un utilisateur n'a rien réservé). Ex : si l'utilisateur 33 a réservé l'objet 12 alors :

  1. écrire une commande libre permettant d'obtenir la liste des objets actuellement libres.
  2. écrire une commande annule permettant à l'utilisateur d'annuler sa réservation.
  3. écrire une commande reserve <numéro> permettant à l'utilisateur de réserver l'objet de numéro spécifié, s'il n'a encore rien réservé.
  4. comment empêcher un utilisateur d'écrire un programme permettant d'annuler ou créer une réservation pour un autre utilisateur que lui-même ? Indiquez quels sont les objets systèmes que vous utilisez/crééz et les droits d'accès afférents.
  5. l'exécution concurrente de ses diverses commandes pose-t'elle problème ? Lesquels ? Décrivez les situations dangereuses ? Comment y remédier ? Corrigez votre code.


Jean-Baptiste Yunes 2001-10-02