Traitement des entrées et des sorties

Cette rubrique présente les considérations relatives à la programmation pour la gestion des entrées-sorties et des sous-programmes de gestion des entrées-sorties (E-S).

Les sous-routines de la bibliothèque d'E-S peuvent envoyer des données vers ou depuis des unités ou des fichiers. Le système traite les unités comme s'il s'agissait de fichiers d'E-S. Par exemple, vous devez également ouvrir et fermer un périphérique comme vous le faites pour un fichier.

Certaines sous-routines utilisent l'entrée standard et la sortie standard comme canaux d'entrée-sortie. Toutefois, pour la plupart des sous-routines, vous pouvez spécifier un fichier différent pour la source ou la destination du transfert de données. Pour certaines sous-routines, vous pouvez utiliser un pointeur de fichier vers une structure qui contient le nom du fichier ; pour d'autres, vous pouvez utiliser un descripteur de fichier (c'est-à-dire l'entier positif affecté au fichier lors de son ouverture).

Les sous-routines d'E-S stockées dans la bibliothèque C (libc.a) fournissent des E-S de flux. Pour accéder à ces sous-routines d'E-S de flux, vous devez inclure le fichier stdio.h à l'aide de l'instruction suivante:
#include <stdio.h>

Certaines des sous-routines de la bibliothèque d'E-S sont des macros définies dans un fichier d'en-tête et d'autres sont des modules d'objet de fonctions. Dans de nombreux cas, la bibliothèque contient une macro et une fonction qui font le même type d'opération. Tenez compte des points suivants lorsque vous décidez d'utiliser la macro ou la fonction:

  • Vous ne pouvez pas définir de point d'arrêt pour une macro à l'aide du programme dbx .
  • Les macros sont généralement plus rapides que les fonctions équivalentes car le préprocesseur remplace les macros par des lignes de code réelles dans le programme.
  • Les macros génèrent un code objet plus grand après la compilation.
  • Les fonctions peuvent avoir des effets secondaires à éviter.

Les fichiers, les commandes et les sous-routines utilisés dans le traitement des E-S fournissent les interfaces suivantes:

Niveau inférieur
L'interface de bas niveau fournit des fonctions d'ouverture et de fermeture de base pour les fichiers et les périphériques.
Flux
L'interface de flux fournit des E-S en lecture et en écriture pour les canaux et les FIFO.
Terminal
L'interface de terminal fournit une sortie formatée et une mise en mémoire tampon.
Asynchrone
L'interface asynchrone fournit des entrées-sorties et des traitements simultanés.
Langage d'entrée
L'interface de langage d'entrée utilise les commandes lex et yacc pour générer un analyseur lexical et un programme d'analyse syntaxique pour l'interprétation des E-S.

Interfaces d'E-S de bas niveau

Les interfaces d'E-S de bas niveau sont des points d'entrée directs dans un noyau, fournissant des fonctions telles que l'ouverture de fichiers, la lecture et l'écriture à partir de fichiers et la fermeture de fichiers.

La commande line fournit l'interface qui permet de lire une ligne à partir d'une entrée standard et les sous-routines suivantes fournissent d'autres fonctions d'E-S de bas niveau:

open, openx ou creat
Préparer un fichier, ou autre objet de chemin, pour la lecture et l'écriture à l'aide d'un descripteur de fichier affecté
read, readx, readv ou readvx
Lecture à partir d'un descripteur de fichier ouvert
write, writex, writev ou writevx
Ecrire dans un descripteur de fichier ouvert
Fermeture
Abandonner un descripteur de fichier

Les sous-routines open et creat définissent des entrées dans trois tables système. Un descripteur de fichier indexe la première table, qui fonctionne comme une zone de données par processus accessible par des sous-programmes de lecture et d'écriture. Chaque entrée de cette table comporte un pointeur vers une entrée correspondante de la deuxième table.

La deuxième table est une base de données par système, ou table de fichiers, qui permet de partager un fichier ouvert entre plusieurs processus. Les entrées de cette table indiquent si le fichier était ouvert en lecture, en écriture ou en tant que canal de communication, et quand le fichier a été fermé. Il y a également un décalage pour indiquer où la prochaine lecture ou écriture aura lieu et un pointeur final pour indiquer l'entrée dans la troisième table, qui contient une copie de l'i-node du fichier.

La table de fichiers contient des entrées pour chaque instance d'une sous-routine open ou create sur le fichier, mais la table i-node ne contient qu'une entrée pour chaque fichier.

Remarque: Lors du traitement d'une sous-routine open ou creat pour un fichier spécial, le système appelle toujours la sous-routine open de l'unité pour autoriser tout traitement spécial (tel que le rembobinage d'une bande ou l'activation d'un modem compatible avec le terminal de données). Toutefois, le système utilise la sous-routine close uniquement lorsque le dernier processus ferme le fichier (c'est-à-dire lorsque l'entrée de la table i-node est libérée). Cela signifie qu'un appareil ne peut pas conserver ou dépendre d'un nombre d'utilisateurs à moins qu'un appareil à usage exclusif (qui empêche la réouverture d'un appareil avant sa fermeture) ne soit implémenté.

Lorsqu'une opération de lecture ou d'écriture se produit, les arguments de l'utilisateur et l'entrée de la table de fichiers sont utilisés pour configurer les variables suivantes:

  • Adresse utilisateur de la zone cible d'E-S
  • Nombre d'octets pour le transfert
  • Emplacement actuel dans le fichier

Si le fichier auquel il est fait référence est un fichier spécial de type caractère, le sous-programme de lecture ou d'écriture approprié est appelé pour transférer les données, ainsi que pour mettre à jour le nombre et l'emplacement en cours. Sinon, l'emplacement en cours est utilisé pour calculer un numéro de bloc logique dans le fichier.

Si le fichier est un fichier ordinaire, le numéro de bloc logique doit être mappé à un numéro de bloc physique. Il n'est pas nécessaire de mapper un fichier spécial de type bloc. Le numéro de bloc physique résultant est utilisé pour lire ou écrire l'unité appropriée.

Les pilotes de périphérique de bloc peuvent permettre de transférer des informations directement entre l'image centrale de l'utilisateur et le périphérique dans des tailles de bloc aussi grandes que les demandes de l'appelant sans utiliser de tampons. La méthode consiste à configurer un fichier spécial de type caractère correspondant à l'unité brute et à fournir des sous-programmes de lecture et d'écriture pour créer un en-tête de mémoire tampon privé non partagé avec les informations appropriées. Des sous-routines d'ouverture et de fermeture distinctes peuvent être fournies, et une sous-routine de fonction spéciale peut être appelée pour la bande magnétique.

Interfaces d'E-S de flux

Les interfaces d'E-S de flux fournissent des données sous la forme d'un flux d'octets qui n'est pas interprété par le système, ce qui offre une implémentation plus efficace pour les protocoles réseau que le traitement d'E-S de type caractères. Aucune limite d'enregistrement n'existe lors de la lecture et de l'écriture à l'aide d'E-S de flux. Par exemple, un processus lisant 100 octets à partir d'un canal de communication ne peut pas déterminer si le processus qui a écrit les données dans le canal de communication a effectué une seule écriture de 100 octets, ou deux écritures de 50 octets, ou même si les 100 octets provenaient de deux processus différents.

Les entrées-sorties de flux peuvent être des canaux de communication ou des FIFO (fichiers first-in, first-out). Les FIFO sont similaires aux tubes car ils permettent aux données de circuler d'une seule façon (de gauche à droite). Cependant, un FIFO peut se voir attribuer un nom et être accessible par des processus non liés, contrairement à un tube. Les FIFO sont parfois appelés tubes nommés. Etant donné qu'il a un nom, un FIFO peut être ouvert à l'aide du sous-programme fopen d'E-S standard. Pour ouvrir un canal de communication, vous devez appeler la sous-routine pipe , qui renvoie un descripteur de fichier, et la sous-routine d'E-S standard fdopen pour associer un descripteur de fichier ouvert à un flux d'E-S standard.

Remarque: Les données des interfaces d'E-S de flux sont en mémoire tampon au niveau de l'utilisateur et ne peuvent pas écrire les données tant que la sous-routine fclose ou fflush n'est pas exécutée, ce qui peut entraîner des résultats inattendus en cas de mélange avec des E-S de fichier telles que read () ou write ().

Les interfaces d'E-S de flux sont accessibles via les sous-routines et macros suivantes:

fclose
Ferme un flux
feof, ferror, clearerr ou fileno
Vérifier le statut d'un flux
commande fflush
Ecrire tous les caractères actuellement mis en mémoire tampon à partir d'un flux
fopen, freopen ou fdopen
Ouvrir un flux
fread ou fwrite
Effectuer une entrée binaire
fseek, rembobiner, ftell, fgetpos ou fsetpos
Repositionner le pointeur de fichier d'un flux
getc, fgetc, getchar ou getw
Obtention d'un caractère ou d'un mot à partir d'un flux d'entrée
obtient ou fgets
Obtenir une chaîne d'un flux
getwc, fgetwc ou getwchar
Obtenir un caractère large à partir d'un flux d'entrée
getws ou fgetws
Obtenir une chaîne d'un flux
printf, fprintf, sprintf, wsprintf, vprintf, vfprintf, vsprintf ou vwsprintf
Imprimer la sortie formatée
putc, putchar, fputc ou putw
Ecrire un caractère ou un mot dans un flux
puts ou fputs
Ecrire une chaîne dans un flux
putwc, putwchar ou fputwc
Ecrire un caractère ou un mot dans un flux
putws ou fputws
Ecrire une chaîne de caractères large dans un flux
scanf, fscanf, sscanf ou wsscanf
Convertir l'entrée formatée
setbuf, setvbuf, setbuffer ou setlinebuf
Affecter la mise en mémoire tampon à un flux
ungetc ou ungetwc
Renvoyer un caractère dans le flux d'entrée

Interfaces d'E-S de terminal

Les interfaces d'E-S de terminal fonctionnent entre un processus et le noyau, fournissant des fonctions telles que la mise en mémoire tampon et la sortie formatée. Chaque terminal et pseudo-terminal possède une structure tty qui contient l'ID de groupe de processus en cours. Ce champ identifie le groupe de processus pour recevoir les signaux associés au terminal. Les interfaces d'E-S de terminal sont accessibles via la commande iostat , qui surveille le chargement des unités du système d'E-S, et le démon uprintfd , qui permet d'écrire les messages du noyau sur la console système.

Les caractéristiques de terminal peuvent être activées ou désactivées à l'aide des sous-routines suivantes:

cfgetospeed, cfsetospeed, cfgetispeedou cfsetispeed
Obtenir et définir les débits en entrée et en sortie en bauds
ioctl
Exécute des fonctions de contrôle associées au terminal
termdef
Caractéristiques du terminal de requêtes
tcdrain
Attentes de la fin de la sortie
fluxtc
Exécute des fonctions de contrôle de flux
tcflush
Supprime les données de la file d'attente spécifiée
tcgetpgrp
Obtient l'ID de groupe de processus d'avant-plan
ctcsendbreak
Envoie une interruption sur une ligne de données série asynchrone
tcsetattr
Définit l'état du terminal
ttylock, ttywait, ttyunlockou ttylocked
Contrôle des fonctions de verrouillage de l'unité tty
ttyname ou isatty
Obtenir le nom d'un terminal
attribut de type de fichier
Recherche l'emplacement dans le fichier utmp pour l'utilisateur en cours

Interfaces d'E-S asynchrones

Les sous-programmes d'E-S asynchrones permettent à un processus de démarrer une opération d'E-S et de renvoyer le sous-programme immédiatement après le démarrage ou la mise en file d'attente de l'opération. Un autre sous-programme doit attendre la fin de l'opération (ou revenir immédiatement si l'opération est déjà terminée). Cela signifie qu'un processus peut chevaucher son exécution avec ses entrées-sorties ou chevaucher des entrées-sorties entre différentes unités. Bien que les E-S asynchrones n'améliorent pas de manière significative les performances d'un processus qui lit à partir d'un fichier disque et écrit dans un autre fichier disque, les E-S asynchrones peuvent fournir des améliorations de performances significatives pour d'autres types de programmes gérés par les E-S, tels que les programmes qui vident un disque sur une bande magnétique ou qui affichent une image sur un écran d'image.

Bien qu'il ne soit pas obligatoire, un processus qui effectue des E-S asynchrones peut demander au noyau de l'avertir lorsqu'un descripteur spécifié est prêt pour les E-S (également appelé E-S pilotées par signal). Lors de l'utilisation de LEGACY AIO, le noyau avertit le processus utilisateur avec le signal SIGIO. Lorsque vous utilisez POSIX AIO, la structure sigevent est utilisée par le programmeur pour déterminer le signal que le noyau doit utiliser pour notifier le processus utilisateur. Les signaux incluent SIGIO, SIGUSR1et SIGUSR2.

Pour utiliser les E-S asynchrones, un processus doit effectuer les étapes suivantes:

  1. Etablissez un gestionnaire pour le signal SIGIO . Cette étape n'est nécessaire que si la notification par le signal est demandée.
  2. Définissez l'ID de processus ou l'ID de groupe de processus pour recevoir les signaux SIGIO . Cette étape n'est nécessaire que si la notification par le signal est demandée.
  3. Activez les E-S asynchrones. L'administrateur système détermine généralement si les E-S asynchrones sont chargées (activées). L'activation a lieu au démarrage du système.

Les sous-routines d'E-S asynchrones suivantes sont fournies:

aio_annuler
Annule une ou plusieurs demandes d'E-S asynchrones en attente
erreur_aio
Extrait le statut d'erreur d'une demande d'E-S asynchrone
aio_fsync
Synchronise les fichiers asynchrones.
aio_nwait
Interrompt le processus d'appel jusqu'à ce qu'un certain nombre de demandes d'E-S asynchrones soient terminées.
aio_lu
Lit de manière asynchrone à partir d'un descripteur de fichier
retour_aio
Extrait le statut de retour d'une demande d'E-S asynchrone
aio_suspendre
Interrompt le processus appelant jusqu'à ce qu'une ou plusieurs demandes d'E-S asynchrones soient terminées
aio_écriture
Ecrit de manière asynchrone dans un descripteur de fichier
lio_listio
Lance une liste de demandes d'E-S asynchrones avec un seul appel
poll ou select
Vérification de l'état d'E-S de plusieurs descripteurs de fichier et files d'attente de messages

Pour une utilisation avec la sous-routine poll , les fichiers d'en-tête suivants sont fournis:

poll.h
Définit les structures et les indicateurs utilisés par la sous-routine poll
aio.h
Définit la structure et les indicateurs utilisés par les sous-routines aio_read, aio_writeet aio_suspend