Précédent Remonter

3  Implémentation de la bibliothèque

L'implémentation décrite ici est une implémentation possible des bibliothèques. L'implémentation effectivement réalisée sous Unix diffère quelque peu mais l'esprit reste le même.

3.1  la structure _iob

La bibliothèque est structurée autour d'une structure de données regroupant toutes les informations nécessaires à la gestion des fichiers. Cette structure est un tableau _iob déclaré
      #define NULL       0
      #define EOF        (-1)
      #define BUFSIZ     1024 
      #define OPEN_MAX   20
      
      typedef struct _iobuf {
          int    cnt ;    
          char   *ptr ;     
          char   *base ;    
          int    bufsiz ; 
          short  flag ;    
          int    file ;      
      } FILE ;              
      extern FILE _iob[OPEN_MAX] ;                                     
OPEN_MAX est le nombre maximal de fichiers pouvant être simultanément ouverts. BUFSIZ est la taille des buffers. Les différents champs d'une structure _iobuf sont :
int cnt
le nombre de caractères restants dans le buffer ;

char *ptr
est la position, dans le buffer, du prochain caractère à traiter ;

char *base
est le buffer associé au fichier ;

short flag
est un indicateur indiquant le mode du fichier ; nous nous limiterons aux valeurs :
    #define IOREAD  01
    #define IOWRIT  02
    #define IOEOF   020    
    
qui indique respectivement que le fichier est ouvert en lecture, en écriture ou que la fin de fichier a été atteinte ;

int file
est le descripteur autorisant l'accès au fichier par les appels systèmes.

3.2  Fonctionnement

Lors de l'ouverture d'un flot (fopen()), on recherche un élément libre dans le tableau _iob à partir du début du tableau. Un pointeur vers cet élément sera retourné en cas de succès. L'initialisation des différents champs est alors réalisée2.

Les appels des fonctions bibliothèques auxquelles sont passés le pointeur sur l'élément du tableau _iob (FILE*) mettent à jour cet enregistrement et réalisent pour ce faire des appels systèmes.

3.3  Les entrées/sorties standard

Les fichiers d'entrées et de sorties standard sont définis par des macros :
 
      #define stdin    (&_iob[0])
      #define stdout   (&_iob[1])
      #define stderr   (&_iob[2])   
et le tableau _iob est initialisé avec
 
      FILE _iob [OPEN_MAX] = {       
          { 0, (char *) 0, (char *) 0, IOREAD, 0 },
          { 0, (char *) 0, (char *) 0, IOWRIT, 1 },   
          { 0, (char *) 0, (char *) 0, IOWRIT | IOUNBUF, 2 }} ;
les deux fichiers stdout et stderr sont ouverts en écriture, les écritures sur stderr sont réalisées sans passer par un tampon, le fichier stdin est ouvert en lecture.
Exercice 1   Écrire les appels bibliothèques fopen(), fclose(), fputc(), fgetc(), et ungetc() à partir des appels systèmes open(), close(), read(), et write().

Exercice 2   Quel sont les avantages de la bibliothèque sur les appels systèmes ? Pour vous persuader de ces avantages, écrire différentes versions de la commande cat qui recopie son entrée standard sur sa sortie standard. Comparez les temps d'exécution (avec la commande time, cf. man 1 time) d'une version « appels systèmes » et d'une version « bibliothèque ».


Précédent Remonter