Les Entrées/Sorties sous UNIX 1 UNIX Introduction Entrée/Sortie : Physique et
Les Entrées/Sorties sous UNIX 1 UNIX Introduction Entrée/Sortie : Physique et Logique (Virtuelle) Le système d'exploitation implémente des E/S virtuelles Processus {T.D.F} 2 Processus {T.D.F} T.D.F Association entre P. Physique et P. Virtuel Déroulement d'une E/S • Le processus demande une L/E. • Interruption : Sauvegarde du contexte du processus. Le processus change d'état. • Le noyau active le traitant d'interruption adéquat. • Le traitant d'interruption active le pilote de périphérique. 3 • Le traitant d'interruption active le pilote de périphérique. • Le pilote de périphérique réalise l'opération d'E/S physique en appelant le contrôleur de périphérique (mode de transfert). • Le contrôleur de périphérique réalise le transfert de données. • Le noyau dépose les données dans l'espace utilisateur et retire le processus de la file des processus en attente. Appels système • Descripteur de fichier : entier naturel décrivant un fichier (sens large) ouvert. • Le descripteur de fichier est utilisé dans les primitives de gestion des fichiers. 4 • int open(const char *path, int flags, [mode_t mode]) -1 en cas d'erreur (errno) Sinon entier naturel (>2). – path: chemin vers le fichier à ouvrir. – flags: types d'opérations qui seront effectuées sur le fichier (O_RDONLY, O_WRONLY, O_CREAT, O_APPEND, O_RDWR) – mode: utilisé avec O_CREAT (mode d'accès, umask) Appels système (suite) • int read(int handle, void *buffer, size_t octets) – handle: Descripteur de fichier renvoyé par open() – buffer: Zone mémoire dans laquelle les données lues (depuis le fichier handle seront) stockées. – octets: Le nombre d'octets qui seront lus. La fonction peut lire moins de octets octets. 5 lire moins de octets octets. – Valeur de retour : Le nombre d'octets effectivement lus. Elle retourne zéro si tentative de lecture depuis la fin de fichier et -1 en cas d'erreur (errno). Appels système (suite) int getchar( ) { char c; Version non bufférisée de la macro getchar() 6 return (read(0,&c,1)==1)?(unsigned char) c : EOF; } Appels système (suite) • int write(int handle, void *buffer, size_t octets) – handle: Descripteur de fichier renvoyé par open() – buffer: Zone mémoire à partir de laquelle les données seront lues pour être écrites dans le fichier. – octets: Le nombre d'octets qui seront écrits. La fonction peut écrire moins de octets octets. 7 peut écrire moins de octets octets. – Valeur de retour : Le nombre d'octets effectivement écrits. Elle retourne -1 en cas d'erreur (errno). Appels système (suite) int putchar(char c) Version non bufférisée de la macro putchar() 8 { return (write(1,&c,1)==1)?(unsigned char) c : EOF; } Appels système (suite) • int close(int handle) : Permet de fermer le fichier décrit par handle. Elle renvoie 0 en cas de succès ou -1 en cas d'échec. • off_t lseek(int desc, off_t depl, int origine) : Permet de déplacer la tête de L/E dans le fichier décrit par desc, de depl octets depuis origine. 9 origine. Le paramètre origine ne peut avoir que l'une des valeurs suivantes : SEEK_SET (début du fichier), SEEK_CUR (position courante dans le fichier) ou SEEK_END (fin du fichier). Elle renvoie la nouvelle position dans le fichier exprimée par rapport au début du fichier ou -1 en cas d'échec. • Fichiers spéciaux : – 0 : stdinSTDIN_FILENO Entrée standard – 1 : stdoutSTDOUT_FILENO Sortie standard – 2 : stderrSTDERR_FILENO Erreur standard Appels système (suite) 10 – 2 : stderrSTDERR_FILENO Erreur standard Tuyaux (Tubes ou encore pipes) • Principe • Utilité Un processus envoie des données à un autre processus. L'opération d'envoi passe directement par la mémoire centrale (pas de stockage temporaire sur disque) 11 • Principe – Côté écrivain et côté lecteur : Chaque côté est matérialisé par un descripteur de fichier (ouvert en Lecture ou en Écriture) – Lecture bloquante Synchronisation. – Lecture est destructive. int pipe(int tuyau[2]) : Permet de créer un tuyau. tuyau est un Tuyaux (Tubes ou encore pipes) (suite) $ ls ¦ wc –l Le Shell relie la sortie standard de la commande ls à l'entrée standard de la commande wc au moyen d'un tuyau (tube). 12 int pipe(int tuyau[2]) : Permet de créer un tuyau. tuyau est un tableau de deux descripteurs de fichier telle que : tuyau[0] : Descripteur utilisé côté lecture. tuyau[1] : Descripteur utilisé côté écriture. Processus écrivain ls wc –l Processus lecteur tuyau[1] tuyau[0] Espace mémoire Redirection des entrées/sorties • Principe : Relier la sortie standard d'un processus à l'entrée standard de l'autre. $ ls ¦ wc –l ls: Normalement écrit ses donnés sur la sortie standard 13 • Les fonctions dup() et dup2() sont utilisées pour résoudre ce problème : Dupliquer un descripteur de fichier. ls: Normalement écrit ses donnés sur la sortie standard (écran du terminal). De même pour wc, normalement lit ses données depuis l'entrée standard (clavier du terminal) Redirection des entrées/sorties (suite) • Comment se fait la redirection ? - Exemple de l'entrée standard : 1. Fermer STDIN_FILENO 14 1. Fermer STDIN_FILENO 2. Appeler dup(tuyau[0]) : l'entrée standard est connectée au descripteur côté lecture du tuyau. 3. Fermer le descripteur côté lecture du tuyau (il est devenu inutile, car on accède depuis l'entrée standard) Redirection des entrées/sorties (implémentation de ls ¦ wc –l ) int main(void) { int tube[2]; if(!pipe(tube)) /* Création du tuyau */ { switch(fork()) /* Création d'un processus */ { case 0: /* Fils : processus écrivain */ close(tube[0]); /* Fils : écrivain, ferme le côté lecture du tube */ 15 close(tube[0]); /* Fils : écrivain, ferme le côté lecture du tube */ dup2(tube[1],STDOUT_FILENO); /* Redirection de la sortie standard de la commande "ls" */ close(tube[1]); /* Devient inutile après la redirection */ execlp("ls","ls",NULL); /* Recouvrement avec l'exécutable "ls" */ default: /* Père : processus lecteur */ close(tube[1]); /* Père : lecteur, ferme le côté écriture du tube */ dup2(tube[0],STDIN_FILENO); /* Redirection de l'entrée standard de la commande "wc" */ close(tube[0]); /* Devient inutile après la redirection */ execlp("wc","wc"," –l", NULL); /* Recouvrement avec l'exécutable "wc" */ } exit(EXIT_SUCCESS); } perror("pipe"); exit(EXIT_FAILURE); } Redirection des entrées/sorties (implémentation de ls ¦ wc –l ) int main(void) { int t[2]; /* Les deux descripteurs du tube */ if (!pipe(t)) /* Création réussie du tube */ { if(fork()) /* Père : il est écrivain */ { close(t[0]); /* Car le père est écrivain ! */ dup2(t[1], STDOUT_FILENO); execlp("ls","ls", NULL); 16 execlp("ls","ls", NULL); perror("execlp"); exit(EXIT_FAILURE); } else /* Fils : il est lecteur */ { close(t[1]); /* Car le fils est lecteur ! */ dup2(t[0], STDIN_FILENO); execlp("wc","wc", "-l", NULL); perror("execlp"); exit(EXIT_FAILURE); } return 0; } La commande cat int main(int argc, char *argv[ ]) { FILE *fp; void copie_fichier(FILE *, FILE *); if(argc==1) /* Pas de paramètres : Copier stdin sur stdout */ copie_fichier(stdin,stdout); else while(--argc >0) { if((fp=fopen(*++argv,"r"))==NULL) 17 if((fp=fopen(*++argv,"r"))==NULL) { fprintf(stderr,"Problème d'ouverture de %s",*argv); return 1; } copie_fichier(fp,stdout); fclose(fp); } return 0; } La commande cat (suite) void copie_fichier(FILE *entree, FILE *sortie) { int c; while((c=getc(entree))!= EOF) 18 while((c=getc(entree))!= EOF) putc(c,sortie); } uploads/Industriel/ chapitre-3-les-entrees-sorties.pdf
Documents similaires










-
29
-
0
-
0
Licence et utilisation
Gratuit pour un usage personnel Attribution requise- Détails
- Publié le Oct 01, 2022
- Catégorie Industry / Industr...
- Langue French
- Taille du fichier 0.0888MB