Examen de Systèmes I -- Licence -- Septembre 2005
Quelles sont les conditions nécessaires pour que, dans un système de fichier «Unix», un utilisateur puisse:
- créer un fichier ordinaire ? et un répertoire ?
- supprimer un fichier ordinaire ? et un répertoire ?
Soit l'instruction open("f",O_CREAT+O_RDWR,S_IROTH);
.
- À quelles conditions cet appel à; la fonction
open
ne produira pas d'erreur ?
- En cas de réussite de cet appel, que peut-on dire des droits d'accès du fichier
f
?
Soit le programme suivant:
#include <touskilfo.h>
int main(int argc,char *argv[]) {
int d1, d2, d3, d4, lus; char buf[7]; buf[6] = 0;
d1 = open("f",O_CREAT|O_TRUNC|O_RDWR,S_IRWXU);
/* point 1 */
d2 = open("f",O_RDWR);
d3 = dup(d1);
write(d1,"abcdef",6);
lus = read(d1,buf,6); printf("J'en ai lu %d %s\n",lus,lus?buf:"[rien]");
lus = read(d2,buf,6); printf("J'en ai lu %d %s\n",lus,lus?buf:"[rien]");
lus = read(d3,buf,6); printf("J'en ai lu %d %s\n",lus,lus?buf:"[rien]");
write(d1,"abcdef",6);
lus = read(d1,buf,6); printf("J'en ai lu %d %s\n",lus,lus?buf:"[rien]");
lus = read(d2,buf,6); printf("J'en ai lu %d %s\n",lus,lus?buf:"[rien]");
lus = read(d3,buf,6); printf("J'en ai lu %d %s\n",lus,lus?buf:"[rien]");
d4 = open("f",O_RDWR);
unlink("f");
lus = read(d4,buf,6); printf("J'en ai lu %d %s\n",lus,lus?buf:"[rien]");
close(d1), close(d2), close(d3), close(d4);
return EXIT_SUCCESS;
}
On supposera que les conditions «normales» d'exécution des fonctions seront remplies (pas d'échecs dus à; des erreurs «tordues»).
- que produira à; l'écran l'exécution de ce programme ?
- dessinez les différentes tables pertinentes du système de gestion de fichiers et leurs évolutions lors des appels successifs aux différentes fonctions
open
, dup
et close
.
- expliquez ce qui se passe lors de l'appel à;
unlink
.
- si pendant que le contrôle est au
point 1
, et que par ailleurs dans le système la chaîne
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
est écrite en position 0 dans le fichier f
, quels seront les messages alors affichés lors de l'exécution ?
Soit l'extrait suivant du manuel en ligne d'un système «Unix»:
SYNOPSIS
#include <sys/uio.h>
int readv(int fd, const struct iovec *vector, int count);
struct iovec {
void *iov_base; /* Adresse de début. */
size_t iov_len; /* Longueur en octets. */
};
DESCRIPTION
readv lit les données depuis le descripteur de fichier fd, et place le
résultat dans les buffers décrits par vector. Le nombre de buffers
est indiqué par count. Les buffers sont remplis dans l'ordre
spécifié. Le fonctionnement est identique à read à la seule
différence que les données sont écrites dans vector plutôt que dans un
buffer contigu.
Votre système ne disposant pas d'une telle fonction, il vous est demandé de la réécrire en utilisant les fonctions d'entrées/sorties de base.
- écrivez en C le code de la fonction.
- que pensez-vous de l'atomicité d'un appel à; cette fonction ?
Écrire une commande permettant de tester si une référence donnée est accessible par un utilisateur donné dans un mode donné. Cette commande aura comme prototype:
accessible utilisateur mode référence. Cette commande renverra 0 en cas de succès et n'importe quoi d'autre en cas d'échec (dans ce cas on pensera à; envoyer sur la sortie erreur des messages suffisamment explicites pour l'utilisateur). L'argument mode sera constitué de n'importe quelle combinaison des caractères r (pour désigner un accès en lecture), w (pour désigner un accès en écriture) et x (pour désigner un accès en exécution). Voici un exemple d'exécution de cette hypothétique commande:
<253-[17:46]> accessible mz r /etc/passwd
<254-[17:46]> accessible gastin rw /etc/passwd
ecriture dans /etc/passwd impossible
<255-[17:46]> accessible hf r /home/automate/yunes/essai/bidule/truc/much/gnark
traversee de /home/automate/yunes/essai impossible
<256-[17:57]> accessible bizarre rwx /tmp
accessible : Utilisateur bizarre inconnu
<257-[17:47]> accessible hf rdf /tmp
accessible : Mode rdf inconnu
Vous pouvez utiliser (si nécessaire) la fonction struct passwd *getpwnam(const char *username); permettant de récupérer les informations relatives à; l'utilisateur de nom donné. La structure comprend différents champs dont pw_uid et pw_gid contenant respectivement l'UID et le GID de l'utilisateur.