Examen de Systèmes I -- Licence -- Septembre 2005

Exercice

Quelles sont les conditions nécessaires pour que, dans un système de fichier «Unix», un utilisateur puisse:
  1. créer un fichier ordinaire ? et un répertoire ?
  2. supprimer un fichier ordinaire ? et un répertoire ?

Exercice

Soit l'instruction open("f",O_CREAT+O_RDWR,S_IROTH);.
  1. À quelles conditions cet appel à; la fonction open ne produira pas d'erreur ?
  2. En cas de réussite de cet appel, que peut-on dire des droits d'accès du fichier f ?

Exercice

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»).
  1. que produira à; l'écran l'exécution de ce programme ?
  2. 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.
  3. expliquez ce qui se passe lors de l'appel à; unlink.
  4. 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 ?

Exercice

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.
  1. écrivez en C le code de la fonction.
  2. que pensez-vous de l'atomicité d'un appel à; cette fonction ?

Exercice

É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.