Examen de Systèmes II
Licence - Septembre 2001
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");
}
}
- quels sont les affichages possibles à l'exécution d'un tel programme ?
Justifiez.
- quel mécanisme utiliseriez-vous pour garantir un ordre donné sur les
messages ? Écrivez le code correspondant.
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);
}
- 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.
- dans quel ordre les processus se terminent-ils ?
- si l'on supprime la seconde boucle for() et son contenu.
Quelle différence cela fait-il ?
- et si l'on remplace la seconde boucle for() et son contenu par
un simple appel à wait(NULL) ?
É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.
- pour un shell, qu'est ce qu'une commande interne/externe ?
- quelles sont les commandes qui ne peuvent être qu'internes ? et
pourquoi ?
- pourquoi certains shells proposent-ils en interne des commandes comme
ls ?
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 :
- le 33e int du fichier utilisateurs contiendra la
valeur 12,
- le 12e int du fichier objets contiendra la valeur
33.
- écrire une commande libre permettant d'obtenir la liste des
objets actuellement libres.
- écrire une commande annule permettant à l'utilisateur d'annuler
sa réservation.
- é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é.
- 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.
- 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