Introduction

Nous allons décrire ici les outils permettant de définir et manipuler les fichiers ainsi que les interfaces permettant d’accéder à des fichiers.

Nous verrons également que ces interfaces permettent l’accès à d’autres outils d’échange d’information. C’est en effet une pratique classique que de proposer une interface la plus simple et la plus homogène possible à tous les outils de stockage et d’échange de données.

Nous allons commencer par essayer de définir clairement les deux principales structures de données classiquement utilisées : le noeud d’index et le fichier ouvert.

La première de ces structures donne des informations sur la structure et les propriétés du fichier ; c’est au travers d’elle que nous pourrons savoir où se trouve physiquement le fichier, à qui il appartient, qu’est-ce qu’un utilisateur a le droit d’en faire, etc …

La seconde contient des informations plus dynamiques sur un fichier qui est manipulé par une tâche. On y trouvera donc par exemple la position actuelle dans le fichier.

Une analogie simple nous permet de dire que le nœud d’index nous permet de savoir qu’un livre est situé dans la troisième rangée de la deuxième étagère (et qu’il est interdit d’écrire sur le livre !), la où le fichier ouvert contient par exemple un marque page positionné à la prochaine page qu’un utilisateur s’apprète à lire.

Notion de noeud d’index

La structure permettant de décrire les propriétés d’un fichier est classiquement appelée nœud d’index, ou plus souvent inode (pour index node).

Dans ManuX

ManuX définit la structure NoeudI et les fonctions associées dans le fichier include/manux/noeudi.h (dox) . Les fonctions sont implantées dans le fichier sf/noeudi.c (dox) .

Une chose importante à avoir en tête est le fait qu’un fichier décrit par un NoeudI peut être de diverses natures et qu’il est donc important de garder trace d’informations permettant de savoir comment le manipuler.

La structure NoeudI intègre en particulier les champs suivants :

  • methodesFichier fourni les fonctions de manipulation d’un fichier du type concerné.

  • prive est un pointeur vers des données spécifiques au type du fichier et permettant de définir des propriétés spécifiques du fichier.

Les méthodes de manipulation des fichiers

Description d’un fichier ouvert

Dans ManuX

Dans ManuX, un fichier ouvert est décrit dans la structure fichier qui contient en particulier les données suivantes

  • noeudI

  • prive est un pointeur vers des données spécifiques au type du fichier et permettant de conserver trace de l’état du fichier.

Outils de base de manipulation des fichiers

Interface utilisateur

L’interface fournie à l’espace utilisateur est généralement simple et la plus abstraite possible. Elle passe par un certain nombre d’appels système permettant en particulier d’ouvrir, de lire, d’écrire et de fermer un fichier.

Dans le noyau

Dans ManuX

ManuX définit une interface utilisateur classique fondée sur quelques appels systèmes inspirés de ce que l’on trouve dans un système Unix.

L’interface

Ouverture d’un fichier

L’ouverture d’un fichier se fait à l’aide de l’appel système UNDEFINED.

Lecture dans un fichier

L’appel système lire est défini dans le fichier

usr/include/stdio.h (dox) de la façon suivante :

int lire(int fd, void * buffer, int nb);

Écriture dans un fichier

Dans le noyau

Lecture dans un fichier

L’implantation de l’appel système de lecture est réalisée dans la fonction sys_lire() implantée dans le fichier

sf/fichier/c.. (dox) L’appel système est défini dans la fonction sfInitialiser() du même fichier.

Cette fonction peut servir en particulier à mettre en place des contrôles de sécurité. Elle se contente pour le moment de faire appel à la fonction fichierLire() qui est en charge d’aiguiller vers la fcontion de lecture spécifique au type du fichier ciblé.

Un exemple : les consoles

Je ne vais pas revenir ici sur l’implantation des consoles, déjà décrite avec brio dans le chapitre qui leur est dédié. Regardons simplement comment elles se retrouvent affublées d’une interface de type fichier.

Dans le fichier lib/console.c (dox) , les fonctions de manipulation d’une console sont définies de la façon suivante

/**
 * @brief Declaration des methodes permettant de traiter une console
 * comme un fichier
 */
MethodesFichier consoleMethodesFichier = {
   .ouvrir = consoleOuvrir,
   .ecrire = consoleEcrire,
   .lire = consoleFichierLire
};

La fonction d’écriture

La fonction consoleEcrire() est alors simplement constituée d’un appel à la fonction d’affichage dans la console visée, dont un pointeur est obtenu via le champ privé.

ATTENTION ! il faut aller le chercher via le noeudI, ce qui n’est pas le cas pour le moment !!!

Les tubes de communication

Les méthodes de manipulation