0% ont trouvé ce document utile (0 vote)
7 vues12 pages

Entrees Sorties de Bas Niveau

Le document décrit le cycle de vie d'un fichier, incluant les opérations de création, ouverture, lecture, écriture, fermeture et destruction, ainsi que les appels système associés. Il explique également les opérations de bas niveau sur les fichiers, les attributs des fichiers sous UNIX, et les fonctions de la bibliothèque C qui servent d'interfaces de haut niveau. Enfin, il aborde la modification des droits d'accès et du propriétaire, ainsi que les opérations de lecture et d'écriture avec des exemples pratiques.

Transféré par

Abdesslam Nfissi
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
7 vues12 pages

Entrees Sorties de Bas Niveau

Le document décrit le cycle de vie d'un fichier, incluant les opérations de création, ouverture, lecture, écriture, fermeture et destruction, ainsi que les appels système associés. Il explique également les opérations de bas niveau sur les fichiers, les attributs des fichiers sous UNIX, et les fonctions de la bibliothèque C qui servent d'interfaces de haut niveau. Enfin, il aborde la modification des droits d'accès et du propriétaire, ainsi que les opérations de lecture et d'écriture avec des exemples pratiques.

Transféré par

Abdesslam Nfissi
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

7.

ENTREES SORTIES DE BAS NIVEAU

7.1 CYCLE DE VIE D'UN FICHIER

Définitions

Rappelons les définitions et les opérations de base sur les fichiers.

• Le fichier doit être créé, préalablement à toute opération. C'est l'opération de


création.

• Lors de son utilisation, il est nécessaire d'initialiser certaines données internes.


C'est l'opération d'ouverture.

• Il est ensuite possible de lire ou d'écrire des données. On définit ainsi les
opérations de lecture et d'écriture.

• Après utilisation, le fichier doit être refermé. Il pourra bien évidemment être
réutilisé. C'est l'opération de fermeture.

• La suppression du fichier réalise l'opération de destruction.

Appels systèmes de gestion des fichiers

Les appels système associés aux opérations décrites précédemment sont :

creat création du fichier et gestion de ses droits d'accès

open ouverture du fichier (lecture, écriture, mis à jour)

write écriture

read lecture

lseek positionnement du pointeur

close fermeture d'un fichier

link création d'un lien (nom synonyme)

unlink suppression d'un lien

chmod modification des droits d'accès

stat informations sur l'état d'un fichier

access contrôle des droits d'accès.

Les appels système creat et open utilisent le nom externe du fichier (chemin d'accès ou
pathname). Tous les autres utilisent son nom interne (descripteur logique du fichier).

La destruction d'un fichier n'est effective que lorsque tous les chemins d'accès le
désignant dans le système de fichiers sont détruits.
Le cycle de vie d'un fichier et les appels système correspondants sont résumés dans le
schéma suivant :

Cycle de vie d'un fichier

7.2 OPERATIONS DE BAS NIVEAU SUR LES FICHIERS

7.2.1 Opérations de bas niveau et fonctions de la bibliothèque C

Les appels système

Les appels systèmes de gestion des fichiers sont des primitives d'entrées/sorties de bas
niveau qui permettent de réaliser les opérations de base sur les fichiers.

La bibliothèque C

Les fonctions de la bibliothèque C sont des interfaces de haut niveau des appels
systèmes. Elles permettent de réaliser des opérations d'entrée/sortie beaucoup plus
complexes.

7.2.2 Attributs des fichiers

Dans l'environnement UNIX, les attributs des fichiers sont les suivants :

• un propriétaire (le créateur en général) dont l'identité est modifiable par la


commande SHELL chown. Il faut évidemment être le propriétaire ou l'administrateur
pour pouvoir exécuter cette commande,

• un groupe (c'est-à-dire un ensemble d'utilisateurs) modifiable par la commande


SHELL chgrp,

• des droits d'accès.

Ces droits d'accès sont constitués de trois champs : un pour le propriétaire, un pour le
groupe et un pour le reste des utilisateurs dont chacun précise les accès autorisés en
lecture, en écriture ou en exécution. Un fichier avec les droits rwxr-x--x peut être lu, écrit
et exécuté par le propriétaire, lu et exécuté par le groupe et seulement exécuté par les
autres.

Neuf drapeaux binaires permettent de définir les protections, les droits d'accès, le type
d'utilisation des fichiers.

Si le mode est autorisé, le drapeau est positionné à 1, 0 sinon. Ainsi, le tribits rw- s'écrit
110 en système binaire, 6 en système décimal.

Par exemple, les droits rwxrwxrwx s'écrivent également 777, les droits

r--rw---x s'écrivent 461.


7.2.3 Test des droits d'accès

Synopsis

#include <unistd.h>

int access (char *chemin, int type_access);

Description

Le paramètre est un disjonction logique (opérateur sur les bits |) des constantes :

R_OK accessible en lecture,

W_OK accessible en écriture,

X_OK accessible en exécution,

F_OK test d'existence du fichier.

7.3 MODIFICATION DES ATTRIBUTS

7.3.1 Modification des droits d'accès

Synopsis

#include <sys/stat.h>

int chmod(const char* ref, mode_t mode_acces);

int fchmod(int fd, mode_t mode_acces);

Description

Le fichier référencé, par son descripteur ou par son nom reçoit les attributs définis par la
variable mode_acces. Le propriétaire effectif du fichier doit être également le
propriétaire du fichier ou le super utilisateur.

Exemple et exercice

Ecrire un programme qui mette en évidence la différence des droits d'accès entre le
propriétaire réel et le propriétaire effectif et qui modifie le propriétaire et le groupe d'un
fichier. On affichera également les droits d'accès du fichier en lecture et en écriture,
après un contrôle de son existence.

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

char *chemin="essai";

void acces_autorise(void)
{if(access(chemin,W_OK))

printf("accès en écriture sur %s interdit au propriétaire réel\n", chemin);

else

printf("accès en écriture sur %s autorisé au propriétaire réel\n",chemin);

int main(void)

{mode_t mode;

if(access(chemin,F_OK)) {printf("fichier %s inexistant\n",chemin); exit(0);}

system("ls -l essai");

acces_autorise();

if(chown(chemin,200,100)==-1) perror("chown");

acces_autorise();

system("ls -l essai");

// résultat

-rwxr-xr-x 1 root other 21100 Mai 03 14:03 essai

-rwxr-xr-x 1 user1 dba 21100 Mai 03 14:03 essai

7.3.2 Modification du propriétaire

Synopsis

#include <sys/stat.h>

int chown(const char* ref, uid_t uid, gid_t gid);

int fchown(int fd, uid_t uid, gid_t gid);

Description

• Modification du propriétaire ou du groupe du fichier.

• Si l'un des bit suid ou guid était positionné, il est supprimé.

• Sur certaines implémentations (BSD), seul l'administrateur peut utiliser cet appel
système.

7.4 CREATION D'UN INODE ASSOCIE A UN FICHIER SPECIAL


L'appel système à utiliser est variable selon le type du fichier créé.

Fichier ordinaire Fichier spécial Tube Lien symbolique

open mknod pipe symlink

creat mkfifo

Synopsis

#include <sys/stat.h>

int mknod(const char *chemin, mode_t droits, dev_t majeur/mineur);

7.5 OPERATIONS SUR LES FICHIERS

7.5.1 Descripteur de fichier

Lors de la création ou de l'ouverture d'un fichier est associé un nombre entier appelé
descripteur de fichier. C'est l'équivalent de l'étiquette logique d'un fichier en FORTRAN
puisque l'utilisateur accède ensuite au fichier par utilisation de son descripteur dans les
appels systèmes.

7.5.2 Ouverture

L'opération d'ouverture retourne le descripteur du fichier après contrôle des droits


d'accès.

Synopsis

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

int open(char *chemin , int mode_ouverture,... mode_t droits);

Description

chemin est le nom externe du fichier, de type quelconque. Pour les répertoire, seule
l'ouverture en lecture est possible et il est recommandé d'utiliser l'appel opendir.

Un appel open peut être bloquant dans les situations suivantes :

• ouverture d'un tube nommé en écriture en l'absence de lecteur ou en lecture en


absence de rédacteur,

• ouverture d'un terminal non prêt.

L'argument mode_ouverture permet de réaliser des opérations d'E/S particulières lors


de l'ouverture et/ou de paramétrer le comportement des opérations de lecture/écriture
ultérieures. Il est construit par disjonction bit à bit de constantes macro définies dans le
fichier <fcntl.h>.

• Cette disjonction comporte

exactement une des trois constantes

O_RDONLY si le fichier chargé est accessible en lecture seulement,

O_WRONLY si le fichier chargé est accessible en écriture seulement,

O_RDWR si le fichier chargé est accessible en écriture et en lecture.

des constantes dont la fonction est de permettre l'exécution d'une opération


particulière ou de modifier le comportement de l'opération. Les constantes essentielles
retenues par la normes POSIX sont :

O_TRUNC si le fichier existe, sa taille devient nulle.

O_CREAT création d'un fichier ordinaire d'une taille vide s'il n'existe pas. Un
paramètre supplémentaire est alors nécessaire pour définir ses droits ultérieurs.

O_EXCL si le drapeau O_CREAT est positionné et que le fichier existe, retourne une
erreur (-1)

O_NOCTTY le terminal courant ne sera pas le terminal de contrôle du processus,

O_APPEND écriture en mode ajout à la fin du fichier,

O_NONBLOCK modifie l'opération d'ouverture bloquante en renvoyant un message


d'erreur avec la variable errno contenant la constante EAGAIN sauf dans le cas d'un
tube nommé.

Sous SYSTEME V, deux drapeaux complémentaires sont définis :

O_SYNC les opérations d'écriture en mode bloc sont synchrones (vidage du cache),

O_NDELAY les opérations normalement bloquantes ne le sont plus et renvoient un


message d'erreur.

7.5.3 Création : appel creat

La création d'un fichier peut être réalisée avec l'appel système creat.

Synopsis

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

int creat(const char *chemin, mode_t droits_acces);


Description

chemin nom du fichier,

droits_acces droits d'accès du fichier.

7.5.4 Lecture et écriture

Les opérations de lecture et d'écriture sont réalisées, après l'ouverture du fichier, par les
appels système read et write.

Synopsis

size_t read(int fd, void* buf, size_t nbyte);

size_t write(int fd, void* buf, size_t nbyte);

avec

fd le descripteur de fichier,

buf l'adresse du premier octet en mémoire de la zone où sera exécutée


l'opération de lecture ou d'écriture,

nbyte le nombre de bytes à transférer.

Exemple : les variables entières nlus et necrits représentent le nombre d'octets


effectivement lus ou écrits lors de l'exécution des appels système read et write.

Cas particuliers

nlus = necrits = 0 fin du fichier rencontrée.

nlus = necrits = -1 erreur en lecture ou en écriture.

Algorithme de lecture

Début

retour -1 si erreur de paramètre d'appel

s'il n'existe pas de verrou exclusif impératif en lecture

alors

si la fin du fichier n'est pas atteinte, alors lecture depuis la position courante de
nbyte caractères au plus (fin de fichier éventuellement atteinte) et retour du nombre
d'octets effectivement lus sinon retour 0

sinon

si le mode de lecture est bloquant (drapeaux O_NOBLOCK et O_NDELAY non


positionnés), alors blocage du processus jusqu'à la suppression du verrou
sinon aucun caractère n'est lu et errno vaut EAGAIN

Fin

Algorithme d'écriture

retour -1 si erreur de paramètre d'appel

s'il n'existe pas de verrou, exclusif, impératif ou partagé en écriture

alors

écriture (asynchrone par défaut, synchrone avec le drapeau O_SYNC) depuis la


position courante ou depuis la fin du fichier (drapeau O_APPEND) de nbyte caractères
au plus et retour du nombre d'octets effectivement écrits.

sinon

si aucun des drapeaux O_NOBLOCK et O_NDELAY n'est positionné, le processus


est bloqué jusqu'à la suppression du verrou

sinon aucun caractère n'est écrit et errno vaut EAGAIN

Fin

Exemple 1

#define BUFSIZE 512

#include <stdio.h>

int main(void)

{/* écriture sur la sortie standard du caractère saisi sur l'entrée standard */

char buf[BUFSIZE];

int n;

while (( n = read(0,buf,BUFSIZE)) >0)

write(1,buf,n);

On peut remarquer dans cet exemple que l'exécution préalable de l'appel système open
n'est pas obligatoire. Dans ce cas, il y a ouverture avec les paramètres par défaut.

Exemple 2

#define BUFSIZE 1024

#define PMODE 644


#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

int main (int argc, char *argv[])

/* écriture simplifiée de la commande UNIX de copie d'un fichier cp */

{int f1,f2,n;

char buf[BUFSIZE];

/* prototype */

void erreur( char *, char *);

int open(char *, int, mode_t);

if(argc != 3) erreur ("Usage : cp depuis vers", (char *) NULL);

if((f1 = open(argv[1], O_RDONLY, 444)) == -1)

erreur("cp : ouverture impossible %s",argv[1]);

if((f2 = creat(argv[2],PMODE)) == -1) erreur("cp : création impossible %s",argv[2]);

while ((n = read(f1, buf, BUFSIZE)) > 0)

{if (n==-1) exit(-1);

if (write(f2, buf, n) != n) erreur("cp : erreur en écriture", (char *) NULL);

exit(1);

return(1);

void erreur(char *s1, char *s2)

{fprintf(stderr,s1,s2);

printf("\n");

exit(-1);

Exemple 3
/* Utilisation des appels système read, write pour écrire une fonction getchar bufférisee
*/

#define BUFSIZE 512

#define CMASK 0377

struct _iobuf

{char *_ptr; /* pointeur sur l'octet courant */

int _rcnt; /* nombre d'octets en lecture dans le tampon */

int _wcnt; /* nombre d'octets en écriture dans le tampon */

char *_base; /* adresse de base du début du tampon */

char _flag; /* mode d'ouverture du fichier */

char _file; /* numéro du fichier */

char _cbuff; /* tampon d'un caractère */

char _pad; /* tampon pour le nombre pair de bytes */

#define putc(c,p) \

(--(p)->_wcnt>=0?((int)(*(p)->_ptr++=(c))) : _flsbf((c),p))

#define putchar(c) putc(c,stdout)

int main(void)

{int c;

while ((c = getchar()) != EOF) putchar(c);

exit(0);

getchar()

{static char buf [BUFSIZE ];

static char *bufp = buf;

static int n = 0;

if (n == 0)

{n = read(0,buf,BUFSIZE);
bufp = buf;

return((--n >=0) ? *bufp++ & CMASK : EOF);

7.5.5 Fermeture

L'appel système close ferme les fichiers ouverts.

Synopsis

#include <unistd.h>

int close(int fd);

Exemple

L'appel système close supprime la connexion entre un fichier ouvert et son descripteur
assurant ainsi la fermeture des fichiers. Bien entendu, le fichier sera réutilisable par la
suite.

7.6 DEPLACEMENT DANS UN FICHIER

Les fichiers ordinaires sont vus comme des fichiers séquentiels par le système
d'exploitation UNIX avec un pointeur sur l'octet courant. Toutefois, l'accès aléatoire aux
différents octets est possible avec l'appel système lseek.

Synopsis

off_t int lseek(int fd, off_t offset , int origine);

Exemple

La variable offset modifie le pointeur sur l'octet courant du fichier dont le descripteur
est fd; la nouvelle position (en octets) est calculée de la façon suivante :

si origine = 0, le déplacement est absolu et croissant par rapport l'origine du


fichier,

si origine = 1, le déplacement est relatif et croissant par rapport la position


courante,

si origine = 2, le déplacement est absolu et croissant par rapport la fin du fichier


(mode ajout).

La norme POSIX a remplacé les valeurs 0, 1, 2 par les constantes SEEK_SET, SEEK_CUR,
SEEK_END.

Exemple : lseek(fd,0L,2);
7.7 APPELS DE COMMANDES DE L'INTERPRETE

On peut, depuis un programme écrit en C, appeler des commandes de l'interprète par


utilisation de l'appel système system.

Synopsis

#include <stdlib.h>

int system(const char *programme);

Exemple : le programme en cours est suspendu. La commande spécifiée par la chaîne


de caractères *programme est exécutée si elle existe (code de retour différent de zéro).
Dans le cas contraire, un code de retour nul est retourné.

Exemples

a) Voici un programme qui permet l'affichage de la date dans l'environnement MS/DOS.

#include <stdio.h>

int main(void)

{system("date");

exit(0);

b) ce programme permet d'exécuter plusieurs commandes (sans argument).

#include <stdio.h>

int main(argc,argv)

int argc;

char *argv[];

{int i;

for(i= 0; i <argc; i++ ) system(*++argv);

exit(0);

// résultat

utilisation : multi date time

Vous aimerez peut-être aussi