            _                                          _   _           
           | |                                        | | (_)          
  ___ _ __ | |_ _ __ ___  ___  ___      ___  ___  _ __| |_ _  ___  ___ 
 / _ \ '_ \| __| '__/ _ \/ _ \/ __|    / __|/ _ \| '__| __| |/ _ \/ __|
|  __/ | | | |_| | |  __/  __/\__ \    \__ \ (_) | |  | |_| |  __/\__ \
 \___|_| |_|\__|_|  \___|\___||___/    |___/\___/|_|   \__|_|\___||___/
                                                                 
 

    -- [ Entres/sorties standarts


Principes gnraux :


On regroupe sous le terme d'   entres/sorties , d une part les oprations 
de lecture et d'criture, et d autre part les oprations de contrle associes.
Une opration d'criture est un transfert de donnes effectu depuis une 
zone mmoire du programme vers une unit priphrique : terminal, unit 
de disque, imprimante, etc. L'opration de lecture est l'opration 
symtrique, c'est--dire un transfert de donnes depuis une unit de 
priphrique vers la mmoire.
 
Ces oprations trs bas niveaux sont ralises par le systmes 
d'exploitation lorsqu un programme excute une requte d entre/sortie, 
encore appel entre/sortie de  bas niveau . Sous un systme compatible 
POSIX, ces requtes correspondent aux fonctions de bas niveau write et 
read.
Les fonctions d'entres/sorties de la bibliothque standard, encore appels 
entres/sorties  de haut niveau  constituent dans ce cas une interface 
avec les entres/sorties de bas niveau. Elles intgrent de plus, des 
mcanismes de formatage/d formatage et des mcanismes d optimisation 
des transferts physiques.

Les entres/sorties peuvent s'effectuer sur des units d'entres/sorties aux 
comportements trs diffrents : terminal, lecteur de disquette, lecteur de 
bande, fichier du systme de fichier,etc. Afin d'unifier les mcanismes 
d'entres/sorties de haut niveau (que nous appellerons simplement 
entres/sorties dans la suite de ce document) s'effectue au moyen d un seul 
type d'unit logique appele flot (de l'anglo-saxon stream). De mme, 
toutes les units physiques sont vues  travers une abstraction unique 
appele fichier. Ce terme de fichier peut donc dsigner un fichier du 
systme de fichiers au sens strict, mais galement un priphrique.
Dans la suite de ce document, nous utilisons la terminologie POSIX de 
fichier ordinaire, rpertoire et fichier spcial pour dsigner 
respectivement un fichier de donnes  accs direct, un fichier rfrenant 
d'autres fichiers, et un fichier reprsentant une unit d'entres/sorties.
	De manire gnrale, il existe deux types de flots :
1 Les flots texte, dont le contenu est dcoup en lignes 
spares par le caractre '\n'. Le contenu du flot peut subir 
des modifications selon les conventions de reprsentation de 
texte de l'environnement, comme par exemple la 
suppression des espaces prcdant le caractre '\n'.

2 Les flots binaires qui permettent de transfrer sans 
altrations le codage interne des donnes.

Sur certains systmes, les flots texte peuvent tre restreints de sortes qu'ils 
peuvent seulement transmettre des caractres affichables et certains 
caractres de contrles. Par contre, les flots binaires ne comportent aucune 
restriction.

Cette distinction entre flots texte et flots binaires est impose par la 
compatibilit avec des systmes dans lesquels les applications orientes 
texte utilisent un format de fichier spcifique. Elle n'a pas de sens sous un 
systme UNIX ou un systme compatibilit POSIX, tous les fichiers tant 
grs de faon homogne.

La manire la plus lmentaire d'effectuer physiquement une entre/sortie 
est de procder caractre par caractre. Cette faon de faire peut convenir 
dans le cas d'entres/sorties effectus sur le terminal. Elle s'avre par 
contre inefficace lors de lectures et d'critures sur disque. Dans ce cas, il 
est prfrable de procder bloc par bloc. On utilise pour cela un tampon, 
c'est--dire une mmoire de travail, o sont stocks les caractres 
transitant par le flot. La norme ISO dfinit trois modes de fonctionnement 
possibles :
		1 Non mmoris (unbuffered) : les caractres sont 
transmis le plus tt possible aprs la requte d'entre/sortie ;

		2 Pleinement mmoris (fully buffered) : par dfaut, les 
caractres sont transmis par blocs de la taille du tampon ;

		3 Mmoris par ligne (line buffered) : par dfaut, les 
caractres sont transmis chaque fois qu'un '\n' est envoy dans le flot ou 
que le tampon est plein. Les caractres peuvent galement tre 
automatiquement transmis lors des requtes de lecture.

L initialisation d'un flot est le rsultat de l'ouverture d'un fichier, effectu 
au moyen de la fonction fopen. Un flot peut tre ouvert en  lecture , en 
 criture  ou en  lecture/criture . Cela conditionne les oprations 
d'entres/sorties qu'il sera possible d'effectuer sur ce flot. Par exemple, 
une opration d'criture chouera sur un flot ouvert en lecture. Le mode de 
fonctionnement du flot est choisi par dfaut en fonction de l'unit 
physique correspondant au fichier.

A chaque flot est associ une paire d'indicateurs compose de l'indicateur 
de fin de fichier et l'indicateur d'erreur, positionnes par certaines 
fonctions d'entres/sorties. Diverses fonctions permettent de tester ou de 
rinitialiser ces indicateurs. Chaque flot possde galement une position 
courante, gnralement initialise au dbut du fichier lors de l'ouverture, 
indiquant la position de l'octet  partir duquel sera effectue la prochaine 
opration de lecture ou d'criture. Chaque opration de lecture ou 
d'criture met  jour la position courante du flot.
	Trois flots sont prdfinis au dmarrage d'un programme :

Stdin : flot initialis en lecture sur l'entre standard (en gnral le clavier 
du terminal)

Stdout : flot initialis en criture sur la sortie standard (en gnral l'cran 
du terminal ou la fentre du processus.)

Stderr : flot initialis en criture immdiate sur la sortie erreur standard (en 
gnral l'cran du  terminal ou de la fentre du processus.)
Le flot stderr est toujours non mmoris.

Un flot est cod par une structure identifie par l'identificateur de type 
FILE. Elle regroupe l'ensemble des informations ncessaires  la mise en 
uvre d'une entre/sortie : type du flot, fichier associ, tampon, taille du 
tampon, mode d'ouverture, indicateurs, position courante dans le fichier 
Dans un programme, un flot est dclar de type FILE *. Il constitue 
l'argument principal de toute opration d'entre/sortie.

Les flots stdin et stdout sont utilisables implicitement au moyen des 
fonctions scanf et printf. Diverses fonctions, comme par exemple fprintf, 
fscanf, fflush permettent de lire et d'crire sur un pass en paramtre.

Les dfinitions ncessaires  la mise en uvre de ces fonctions (dfinition 
du type FILE, dclaration des flots stdin, stdout et stderr) se trouvent 
dans l'en-tte <stdio.h>. Il est par consquent ncessaire de placer la 
directive #include <stdio.h> en tte de tout fichier dans lequel sont 
effectues des entres/sorties standard.



Ouverture et fermeture de flot


Il est possible d'initialiser un nouveau flot au moyen de la fonction fopen 
et de fermer un flot au moyen de la fonction fclose :

#include <stdio.h>
FILE *fopen(const char *chemin, const char *mode);
Int fclose(FILE *flot);

Le paramtre chemin est le nom du fichier  associer au nouveau flot. Le 
flot peut tre initialis en mode  lecture , en mode  criture , en mode 
 lecture/criture . Le mode  criture  permet de crer un nouveau 
fichier, ou de rinitialiser un fichier existant. Le mode  lecture/criture  
permet de faire des mises  jour partielles d'un fichier.

Le paramtre mode dcrit le type d'accs que l'on veut effectuer : lecture 
et/ou criture, et positionnement. C'est une chane forme de l'un des trois 
caractres r, w et a, suivi ventuellement du caractre +. Lors d'une 
ouverture en criture, le fichier peut, soit tre cre si il n'existe pas, soit 
encore initialis, c'est--dire ramen  une taille nulle, s'il existe deja. Par 
dfaut, chaque lecture ou criture met  jour la position courante du flot 
pour la prochaine lecture ou criture.
Ce n'est pas le cas avec le mode a ( append ) qui force automatiquement 
le positionnement du flot a la fin du fichier lors de chaque criture.

Les modes r+, w+ et a+ correspondent  trois faons diffrentes 
d'initialiser le flot en mode lecture et criture. Il est dans ce cas ncessaire 
d'effectuer une synchronisation du flot entre deux oprations de nature 
diffrentes, c'est--dire une lecture aprs une criture ou inversement.

D'autre part, le suffixe b concatn au mode signifie  entre/sortie en 
mode binaire , le mode par dfaut tant le mode  texte . Cette 
distinction n'a pas de sens dans une implmentation POSIX. Les diffrents 
modes d'ouverture sont rsums dans le tableau suivant :

-----------------------------------------------------------------
|Mode 	|Accs	|Positionnement	|Comportement    |		|
|	|	|En ecriture	|Si le fichier   | si le ficher	|
|  	|	|		|Existe          |n'existe pas	|
-----------------------------------------------------------------
|	|	|		|		|		|
| R	|Read	|	--	|	--	|erreur		|
|	|	|		|		|		|
-----------------------------------------------------------------
|	|	|		|		|		|
|W	|Write	|	--	|initialisation	|creation	|
|a	|	| la fin	|	--	|creation	|
|	|	|		|		|		|
-----------------------------------------------------------------
|	|	|		|		|		|
|r+	|read	|	--	|	--	|erreur		|
|w+	|&	|	--	|initialisation	|creation	|
|a+	|write	| la fin	|	--	|creation	|
|	|	|		|		|		|
-----------------------------------------------------------------
|		Suffixe b : entre - sortie binaire		|
-----------------------------------------------------------------


Tab. Paramtrage de l'ouverture d'un flot d'entres/sorties. Les 
modes a et a+ forcent le positionnement  la du fichier lors de chaque 
opration d'criture. Le mode b est sans objet sur un systme compatible 
POSIX.

Lorsque l'ouverture s'effectue sans erreur, la fonction retourne la rfrence 
 un flot. Il y a diverses situations d'erreur : chemin incorrect, fichier 
protg  Dans ces cas-l, la fonction fopen retourne la valeur NULL. 
Par exemple, l'instruction :

FILE *f_init = fopen (init_file_name, "r");

Dclare un flot de nom f_init et l'ouvre en lecture sur le fichier dont le 
nom est contenu dans la chane pointe par init_file_name. Si ce fichier 
n'existe pas ou n'est pas accessible alors la valeur retourne par fopen est 
la valeur NULL.

L'opration symtrique de l'ouverture d'un flot est sa fermeture, ralise 
par la fonction fclose. Cette fonction vide le tampon du flot et ferme la 
communication. Le descripteur de flot pourra tre allou  nouveau par la 
fonction fopen. 

Lors de la fermeture d'un tampon mmoris, celui-ci est automatiquement 
vid, il est donc naturel de fermer tous les flots ouverts avant la 
terminaison d'un processus. De toute manire, il faut savoir que la 
fermeture de flot est automatique lors d'une terminaison normale, c'est--
dire lors du retour  la fonction main ou lors de l'appel  la fonction exit. 

La Macro constante FOPEN_MAX dfinit le nombre maximum 
d'ouvertures simultanes garanties par l'environnement. A savoir que sous 
un systme compatible POSIX le nombre est au minimum 16. Il est 
gnralement plus lev sur un systme UNIX. Sous LINUX 2.0 il est de 
256.
La Macro constante FILENAME_MAX dfinit la taille d'un vecteur 
pouvant contenir le plus long nom de fichier que supporte le systme. Sur 
certains systmes, a priori il n'y a pas de limitation de longueur pour un 
nom de fichier et la variable FILENAME_MAX est fixe  une valeur 
arbitrairement grande. Par consquent, elle ne doit pas tre utilise pour 
dclarer un tampon de lecture de nom de fichier.

Il est possible de redfinir un flot dj initialis, en changeant le fichier qui 
lui est associ. Cette opration correspond  la redirection d'entres/sorties 
classique sous UNIX. Pour cela, on utilise la fonction freopen :
#include <stdio.h>
FILE *freopen (const char *chemin, const char *mode, FILE *flot) ;

Si le descripteur de flot flot est actif, la fonction freopen commence par 
refermer le flot associ. Un nouveau flot est ensuite initialis avec le mme 
descripteur de flot, de mme faon qu avec la fonction open. Si 
l'ouverture russit, la rfrence au nouveau flot est place dans le 
descripteur flot, et la fonction reopen retourne le descripteur flot. Sinon, 
elle retourne la valeur NULL. Il n'y a pas de notification d'erreur si la 
fermeture du premier flot echoue.

L'exemple suivant montre une redirection du flot sortie standard dans un 
fichier de nom execution.log

----- reopen.c------

#include <stdlib.h>
#include <stdio.h>

#define NOM_LOG "execution.log"

int
main(void)
{
	freopen(NOM_LOG, "w", stdout);
	printf("   ) Debut d'execution de reopen  )\n");
	printf("  /                                             / \n");
	printf(" ( Fin d'execution de reopen __ ( \n");
	return EXIT_SUCCESS;
}

----reopen.c----

La premire commande excute dans la session suivante permet de vrifier 
qu'aucun fichier suffix par .log n'existe. C'est donc l'excution de la 
commande reopen qui le cre. Le fichier est ensuite list au moyen de la 
commande POSIX.2 cat. On peux vrifier qu'il contient toutes les lignes 
crites par printf sur la sortie standard.

	| $ ls *.log
	| *.log not found
	| $ reopen ; ls *.log
	| execution.log 
	| $ cat execution.log
	|    ) Debut d'execution de reopen )
	|   /                                             /
	| ( Fin d'execution de reopen __ (
	| $
	| 

Un programme peut dlibrment ignorer les redirections d'entres/sorties 
standard effectues depuis l'interprte de commandes, en effectuant une 
rouverture du terminal auquel il est attach. Par exemple sous UNIX, le 
terminal attach tant reprsent par le fichier spcial /dev/tty l'excution 
de : 
	freopen("/dev/tty", "w" , stdout)

rend un programme insensible aux redirections de sa sortie standard.

La commande noredir suivante recopie une chane reue en argument (ou 
son entre standard dans le cas o il n y a pas d'argument) sur sa sortie 
standard. Auparavant, elle effectue une rouverture de cette sortie standard 
sur le terminal attach au processus.


-----noredir.c-----
#include <stdlib.h>
#include <stdio.h>
#define TTY "/dev/tty"

int
main(int argc, char *argv[])
{
	freopen(TTY, "w", stdout);

	if (argc >1)
	{
		int i;
	
		for (i = 1; i < argc; i++)
			printf("%s", argv[i]);
		printf("\n");
	}
	else
	{
		for(;;)
		{
			int c = getchar();
	
			if ( c == EOF)
				break;
			putchar(c);
		}
	}
	return EXIT_SUCCESS;
}

-----noredir.c-----

L'exemple d'excution suivant illustre l'impossibilit de dtourner les 
sorties du programme noredir, en effectuant une redirection sur le fichier 
spcial /dev/null (Sous UNIX, le fichier spcial /dev/null est associ  une 
unit d'entre/sortie qui fait disparatre toutes les donnes qu'il reoit). Les 
donnes lues par le programme sont typographis en italiques soulignes.

	| $ Les crits s'envolent parfois 
	| Les crits s'envolent parfois
	| $ echo Les crits s'envolent parfois  > /dev/null
	| $
	| $ noredir > /dev/null
	| Des mots
	| Des mots
	| que l'on ne peut dtourner . . .
	| que l'on ne peut dtourner 
	| $ noredir Des mots que l'on ne peut dtourner  > /dev/null
	| Des mots que l'on ne peut dtourner
	| $


Voila pour une petite prsentation sur les entres/sorties standard avec 
quelques subtilits peu connues.

J'espere avoir t assez clair dans ma prsentation et que vous en tirerez 
quelque chose.
Pour toutes critiques, avis, conseils mais aussi flicitations :p je suis ouvert a tout:p
Mais a vous de me trouver .. 


La petite partie obligatoire et qui me tiens a cur les GreetZ :D

Special GreetZ to n0name : bleyme, Night_Fall, ScanX, Tolwin, Icing
		 &   P41f0X (SecurityHack) , Drim (RedKod)


    -- [ Yp3rite
