Licence 2003-2004 Juin 2004
Systèmes II

Premier exercice

Soit le code suivant:
#include <toucekilfo.h>
int main(int argc,char *argv[]) {
  int i; pid_t p;
  printf("Bonjour je m'appelle %d\n",getpid());
  for (i=0; i<argc; i++)
    switch(fork()) {
      case 0: printf("Je suis %d et mon père %d\n",getpid(),getppid());
              main(argc-1,NULL); printf("J'ai terminé: %d\n",getpid());
              exit(0);
      case -1: printf("raté\n"); exit(1);
    }
  for (i=0; i<argc; i++) {
    p = wait(NULL); printf("%d a terminé\n",p);
  }
  exit(0);
}
  1. quels seraient les messages affichés si on l'exécutait sans arguments en ligne de commande ?
  2. quels pourraient être les messages affichés si on l'exécutait avec un argument en ligne de commande ?
  3. combien de processus seraient-ils créés avec $n$ arguments en ligne de commande ?

Deuxième exercice

Soit le code truc.c suivant:
#include <tatooskifo.h>
int main(int argc,char *argv[]) {
  int f;
  printf("euid=%d egid=%d ruid=%d rgid=%d\n",geteuid(),getegid(),getuid(),getgid());
  f = open("f",O_RDONLY);
  if (f==-1) printf("raté\n"); else close(f);
  setuid(getuid());
  printf("euid=%d egid=%d ruid=%d rgid=%d\n",geteuid(),getegid(),getuid(),getgid());
  f = open("f",O_RDONLY);
  if (f==-1) printf("raté\n"); else close(f);
}
Soient les quelques commandes suivantes exécutées depuis un shell:
[poil-aux-oreilles:~/Desktop] yunes% ls -ail truc f
3038992 -rwx---r--  1 yunes  staff      0 14 Jun 11:30 f
3038991 -rwsr-xr-x  1 dany   staff  11756 14 Jun 11:30 truc
[poil-aux-oreilles:~/Desktop]
Quels messages seront affichés à l'exécution de la commande truc ?

Troisième exercice

Écrire une commande de nom environ permettant d'exécuter une commande quelconque avec un environnement modifié afin de tester l'effet de la modification d'une variable sur l'exécution d'une commande. Par exemple:
[raton:~/Desktop] date                   # la date dans l'environnement normal
mardi, 15 juin 2004, 13:47:32 CEST
[raton:~/Desktop] lance LANG en date     # la date en Anglais pour voir
Thu, Jun 15 13:47:47 CEST 2004
Note: l'environnement peut être manipulé par l'intermédiaire de la variable extern char **environ (tableau de chaînes de caractères dont la dernière est le pointeur NULL).

Le prototype de la commande est lance variable valeur commande args....

Problème

On désire réaliser la simulation logicielle du nouveau processeur Untel(R) afin de pouvoir le tester avant production définitive. Le c\oeur du programme de simulation est alors le suivant:
  while(1) {                           // Un processeur ne s'arrête jamais!
    mot = lit(memoire,pc);             // On prend un mot mémoire
    pc += TAILLE_INSTRUCTION;
    switch(extrait_instruction(mot)) { // On extrait le code de l'instruction
      // Instruction arg1 = arg2
      case 0: ecrit(memoire,extrait_arg1(mot),extrait_arg2(mot)); break;
      // Instruction goto arg1
      case 1: pc = extrait_arg1(mot); break;
      case ... /* Le reste */
      // Instruction inconnue
      default: kill(getpid(),SIGILL);
    }
  }
  1. Signaux:
    1. le signal SIGILL est, comme on peut le voir, détourné de son usage pour simuler l'effet de la tentative d'exécution par le simulateur d'une instruction inconnue. Le processus doît pour «récupérer» l'erreur le capturer: quelles instructions sont alors nécessaires ? et où les insérer ?
    2. quel danger y-a-t-il à utiliser SIGILL ?
    3. on aimerait pouvoir contrôler la vitesse de simulation. Un procédé élémentaire consiste à utiliser un signal qui permettra à sa délivrance de continuer la simulation auparavant mise en attente. Quel signal utiliser, quelles instructions sont à insérer ?
  2. IPCs: l'équipe commerciale de Untel(R) a décidé que le marché des machines SMP (Symetric Multi-Processing) était à conquérir. Pour cela il faut réaliser par simulation une étude portant sur le fonctionnement de plusieurs processeurs du même type sur une seule et même mémoire.
    1. quelles instructions sont à rajouter (et où) afin d'obtenir une mémoire partagée pour la simulation ?
    2. y-a-t-il des précautions particulières à prendre en ce qui concerne l'accès à cette mémoire ? Si oui, lesquelles et quel code faut-il rajouter (et où) pour y remédier ?
  3. le contrôle de la simulation se faisant par l'intermédiaire d'un autre processus, on désire par exemple qu'il autorise:
    1. l'activation d'un mode de fonctionnement automatique du simulateur réalisant l'exécution d'une instruction toutes les $n$ secondes (commande AUTO $n$. Écrire un bout de code le réalisant.
    2. l'activation d'un mode manuel (commande MANU) dans lequel l'exécution d'une instruction est explicitement déclenchée par l'utilisateur (par exemple lorsqu'il frappe une certaine commande: SUIVANTE.
  4. on désire que le contrôleur puisse permettre d'«interroger» le simulateur afin d'obtenir de lui certaines informations sur son état (par exemple valeur contenue dans certaines pages mémoire, etc):
    1. quels mécanismes mettriez-vous en \oeuvre pour cela ? Justifiez.
    2. quelle(s) incidence(s) cela aurait-il sur le fonctionnement du simulateur et du contrôleur ? Indiquez quelles modifications sont alors nécessaires.