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 :
-
methodesFichierfourni les fonctions de manipulation d’un fichier du type concerné. -
priveest 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 -
priveest 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