Previous Up Next

6  Cinquième couche logicielle : système de noms de fichier


Exercice 24
 (Structure d’un répertoire)   Les répertoires sont « simplement » des fichiers particuliers. Ils contiennent au minimum une liste de noms (les fichiers et répertoires contenus dans le répertoire) et pour chaque nom un numéro d’inœud associé. Ainsi un répertoire est un tableau dont chaque entrée est le descripteur d’un fichier. Soit struct entry_s le type d’un tel descripteur. La taille du tableau est directement calculable en fonction de la taille d’une entrée et de la taille du fichier-répertoire.

Pour simplifier le retrait d’un fichier dans la liste des fichiers d’un répertoire, on identifie les entrées détruites (par exemple avec une valeur remarquable pour un des champs de entry_s).

Question 1   Donnez la déclaration de la structure de donnée associée à une entrée dans le répertoire : struct entry_s.
Question 2   Proposez un programme qui affiche la liste des fichiers contenu dans un répertoire (le répertoire étant identifié par son numéro d’inœud).
Question 3   Proposez les fonctions utilitaires
unsigned int new_entry(file_desc_t *dir_fd);
int find_entry(file_desc_t *dir_fd, const char *basename);
new_entry() retourne l’index dans un répertoire (vu comme un tableau d’entrées) de la première entrée libre. Le répertoire est identifié par un descripteur de fichier, il a donc préalablement été ouvert.

find_entry() retourne l’index dans un répertoire d’une entrée dont le nom est donnée, une valeur négative si aucune entrée est trouvée.

Question 4   Proposez maintenant les deux fonctions de création et destruction d’une entrée dans un répertoire connu add_entry() et del_entry().

Exercice 25
 (Nom de fichier et inœud)   Il s’agit d’identifier le inœud correspondant à un fichier dont on connaît le nom complet absolu. Cette identification se fait de proche en proche, par exemple pour le fichier /usr/bin/emacs :
  1. on identifie le inœud de la racine / : il est contenu dans le superbloc ;
  2. on recherche un fichier nommée usr dans le répertoire correspondant à ce inœud, on en identifie le inœud ;
  3. on recherche alors un fichier nommé bin dans le répertoire correspondant à ce inœud ;
  4. etc.

Pour réaliser cette opération, on peut écrire successivement les fonctions suivantes :

unsigned int inumber_of_basename(unsigned int idir, const char *basename);
unsigned int inumber_of_path(const char *pathname);
unsigned int dinumber_of_path(const char *pathname, const char **basename);

La fonction inumber_of_basename() retourne le inombre de l’entrée de nom basename (qui ne doit pas comporter de /) dans le répertoire idir, 0 en cas d’échec.

La fonction inumber_of_path() retourne le inombre d’un nom de fichier absolu, 0 en cas d’échec.

La fonction dinumber_of_path() retourne à la fois le inombre d’un nom de fichier absolu, mais aussi le nom relatif de ce fichier dans son répertoire dans le paramètre basename. La valeur retournée pour basename est un pointeur dans pathname.


Exercice 26
 (Une bibliothèque pour travailler avec les fichiers)   La couche finale de votre travail consiste en une bibliothèque d’accès aux fichiers, avec les fonctions de création, suppression, ouverture, lecture, écriture, déplacement, vidage des tampons et fermeture de fichiers en respectant l’interface donnée dans l’encart.

Interface de manipulation de fichiers

/* Most of the following functions returns RETURN_FAILURE (a <0 value)
   in case of failure. */

/*------------------------------
  Initialization and finalization
  ------------------------------------------------------------
   One must mount a volume/file system before any other operation.
   The environement variable $CURRENT_VOLUME contains this partition
   number.   
   A sole file system mount is allowed. The file system must be umount.
*/

int mount();
int umount();

/*------------------------------
  File creation and deletion
  ------------------------------------------------------------*/

/* return RETURN_FAILURE in of failure (pre-existing file, full
   volume...) */ 
int create_file(const char *pathname, enum file_type_e type);

/* return RETURN_FAILURE in of failure (non pre-existing file, non
   empty directory...) */
int delete_file(const char *pathname);

/*------------------------------
  File management
  ------------------------------------------------------------*/

int open_file(file_desc_t *fd, const char *pathname);
void close_file(file_desc_t *fd);
void flush_file(file_desc_t *fd);
void seek_file(file_desc_t *fd, int offset);

/*------------------------------
  File accesses
  ------------------------------------------------------------*/

/* return the conversion to an int of the current char in the file.
   Return READ_EOF if the file is at end-of-file. */
int readc_file(file_desc_t *fd);

/* write a char in the file.
   Fail if there is no place on device. */  
int writec_file(file_desc_t *fd, char c);

/* read nbytes char from the file and copy them in the buffer.
   Return the number of actually read char; READ_EOF if the file is at
   end-of-file. */ 
int read_file(file_desc_t *fd, void *buf, unsigned int nbyte);

/* write nbyte char from the buffer on the file.
   Return the number of char writen, RETURN_FAILURE in case of error. */
int write_file(file_desc_t *fd, const void *buf, unsigned int nbyte);


Previous Up Next