Examen de Systèmes I--Licence--Janvier 2003

Exercice

Si on crée un fichier en utilisant les droits POSIX: S_IRWXU|S_IRGRP|S_IRWXO quels seront les protections effectives si le masque de l'environnement est positionné à la valeur S_IXUSR|S_IWGRP|S_IROTH? Et si l'on ne connaît pas la valeur du masque?

Exercice

Soit le fragment de programme suivant:
d1 = open("f",O_RDWR);
d2 = open("g",O_WRONLY);
for (i=0; i<10; i++) {
    if (read(d1,&c,1)==1) write(d2,&c,1);
}
dup2(d1,d2);
for (i=0; i<10; i++) {
    if (read(d1,&c,1)==1) write(d2,&c,1);
}
Dans cet exercice on ne considère que des fichiers réguliers.
  1. on suppose que le fichier f est de longueur au moins égale à 20. Que contiennent les fichiers f et g après l'exécution du programme?
  2. même question lorsque g est un lien physique sur l'inoeud correspondant à f?
  3. mêmes questions précédentes si l'on ouvre d2 en ajoutant O_APPEND? puis O_NONBLOCK? puis O_TRUNC?

Exercice

Soit le fragment de programme suivant:
void f(int d,char *s) {
    char v;
    off_t l;
    for (;*s!='\0';s++) {
        l=lseek(d,*s,SEEK_SET);
        v = 0;
        read(d,&v,1);
        v++;
        lseek(d,l,SEEK_SET);
        write(d,&v,1);
    }
}
  1. que semble réaliser la fonction f lorsque d désigne bien un descripteur de fichier ouvert par un appel à open("f",O_CREAT|O_TRUNC|O_RDWR,0);?
  2. comment corriger la fonction afin qu'elle continue de fonctionner à l'identique si le descripteur d est aussi ouvert avec le mode O_APPEND?
  3. si ce fragment est exécuté de façon concurrente (dans deux commandes et en «même temps»), quel est le problème?
  4. quelle fonctionnalité POSIX utiliseriez-vous pour corriger le problème? Modifiez en conséquence la fonction.

Exercice

  1. écrire une commande poubelle référence ... qui prend au moins une référence de fichier ou répertoire en argument et déplace les objets correspondants dans un répertoire de nom .corbeille (à créer si nécessaire) situé dans le répertoire privé de l'utilisateur.
  2. écrire une commande vide qui supprime le contenu du répertoire .corbeille (s'il existe) situé dans le répertoire privé de l'utilisateur.
Note: la référence du répertoire privé de l'utilisateur peut être obtenue par un appel à getenv("HOME"); qui renvoit un char *.

Exercice

Soit le programme prog.c suivant:
#include "tooskilfo.h"
int main(int argc,char *argv[]) {
    int d1, d2;
    char c;
    if (argc<3) exit(EXIT_FAILURE);
    d1 = open(argv[1],O_RDONLY);
    d2 = open(argv[2],O_WRONLY);
    while (1) {
        read(d1,&c,1);
        printf("Lu %c\n",c);
        sleep(1); /* attente d'une seconde */
        write(d2,&c,1);
    }
}
On suppose l'existence de deux références t1 et t2.
  1. que se passe-t-il si t1 et t2 désignent des fichiers ordinaires et que l'on exécute prog t1 t2?
  2. que se passe-t-il si t1 et t2 désignent des tubes nommés et que l'on exécute en concurrence prog t1 t2 et prog t2 t1?
  3. que se passe-t-il si en attendant on lance echo -n "a" » t1?
  4. puis echo -n "b" » t2 ?
  5. que cela change-t-il si l'appel à d1 = open(argv[1],O_RDONLY); est remplacé par un appel à
    d1 = open(argv[1],O_RDONLY|O_NONBLOCK);?

Exercice

Votre système possède une référence particulière (/dev/random) permettant d'obtenir (lorsqu'elle est ouverte en lecture) une suite de longueur quelconque de caractères dits aléatoires. Vous venez de découvrir un nouvel algorithme de génération de nombres pseudo-aléatoires, mais n'avez pas la possibilité de modifier le noyau. Comment vous y prendriez-vous (en tant que root) pour implanter votre nouvel algorithme afin que les applications existantes ne nécessitent aucune modification?

Jean-Baptiste Yunès 2003-02-13