Vous êtes sur la page 1sur 9

Chapitre 3

Système de fichiers et entrées/sortie

1. Définition

Le fichier physique est la représentation physique de l'information tandis que le fichier


logique est un identificateur, qui désigne à la fois le fichier physique (i-noeud) et la
représentation logique (nom), c'est-à-dire l'ensemble d'informations tel qu'il est vu par
l'utilisateur.

Les processus accèdent aux fichiers par un ensemble d'appels Systèmes en spécifiant
un fichier par une chaîne de caractères qui constitue le chemin d'accès.

L'i-noeud contient les informations nécessaires à un processus Pour accéder à un fichier,


tels que le propriétaire, les droits d'accès, la taille et la localisation des données dans le
système de Fichiers.

Système de fichiers et entrées/sorties


Page 1 sur 9
Les dates d'accès au fichier donnent les dates de la dernière modification du
fichier, du dernier accès au fichier et de la dernière modification de l'i-noeud.
La table des adresses disque correspond aux numéros des blocs du disque qui
contiennent les données du fichier. Bien que les utilisateurs traitent les données
d'un fichier comme une suite logique d'octets, le noyau sauvegarde les données
dans des blocs du disque non contigus.

Remarque:
 L'i-noeud ne spécifie pas le chemin d'accès au fichier.
 Changer le contenu d'un fichier implique automatiquement un changement dans
l'i-noeud, mais pas l'inverse.
 tout fichier a un i-noeud (index node), mais peut avoir plusieurs noms, chaque nom
étant en relation avec l'i-noeud. Chaque nom est appelé un lien.

Quand un processus crée un nouveau fichier, le noyau lui assigne un i-noeud inutilisé.
Les i-noeuds sont rangés dans le système de fichiers, mais le noyau les lit et les mémorisent
dans une table des i-nœuds lorsqu'il manipule les fichiers.
Le noyau contient deux autres structures de données, la table des fichiers ouverts et la
table des descripteurs de fichier utilisateur.

La table des fichiers ouverts est une structure globale du noyau, mais la table des
descripteurs de fichier utilisateur est allouée pour un processus.

Ces trois tables, construites en mémoire volatile, entretiennent l'état du fichier et son
accès par les utilisateurs. Elles permettent à divers degré de partager l'accès à un fichier.

La table des fichiers préserve le déplacement octet dans le fichier d'où le prochain
read ou write utilisateur débutera, ainsi que les droits d'accès permis au processus qui fait
l'open.

Système de fichiers et entrées/sorties


Page 2 sur 9
2. Descripteur de fichier
Un descripteur de fichier est un entier qui identifie, au sein d'un processus, un fichier ouvert
par ce processus.

/* open retourne un descripteur de fichier... */


int open (const char *path, int oflag, [int mode]);

/* ... utilisé ensuite par les fonctions d'E/S */

int read (int fildes, void *buf, int nbyte);


int write(int fildes, void *buf, int nbyte);
int lseek(int fildes, int offset, int whence);
int close(int fildes);

2.1.Descripteurs de fichiers standards


• Par convention, les trois premiers descripteurs de fichiers (0, 1 et 2): entrée, sortie et
erreur standard

2.2.Redirections des entrées/sorties


Associer un descripteur de fichier donné à un fichier.

Exemple associer le descripteur de fichier donné 1, STDOUT_FILENO, au fichier out les


écritures avec le descripteur STDOUT_FILENO se feront dans le fichier out

a. Primitive POSIX dup()

#include <unistd.h>
int dup(int fildes);

Recherche le plus petit descripteur disponible en fait un synonyme du descripteur fildes les deux
descripteurs partagent la même entrée dans la table des fichiers ouverts du système. Écrire (/lire)
dans ce plus petit descripteur revient à écrire (/lire) dans le fichier référencé par fildes.
NB : Ce plus petit descripteur correspond à un fichier qui vient d’être fermé

b. Primitive POSIX dup2()

Explicitation du descripteur synonyme créé !

#include <unistd.h>
int dup2(int fildes, int fildes2);

Force fildes2 à devenir un synonyme de fildes ferme le descripteur fildes2 préalablement si


nécessaire
Système de fichiers et entrées/sorties
Page 3 sur 9
Exemples

static void
print_inode(const char* str, int fd)
{
struct stat st;
fstat(fd, &st);
fprintf(stderr, "\t%s : inode %d\n", str, st.st_ino)
}
int
main(int argc, char* argv[])
{
int fdin, fdout;
fdin = open(argv[1], O_RDONLY);
fdout = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 666);

fprintf(stderr, "Avant dup2() :\n");


print_inode("fdin", fdin);
print_inode("fdout", fdout);
print_inode("stdin", STDIN_FILENO);
print_inode("stdout", STDOUT_FILENO);

dup2(fdin, STDIN_FILENO);
dup2(fdout, STDOUT_FILENO);

fprintf(stderr, "Apres dup2() :\n");


print_inode("fdin", fdin);
print_inode("fdout", fdout);
print_inode("stdin", STDIN_FILENO);
print_inode("stdout", STDOUT_FILENO);
exit(EXIT_SUCCESS);
}

3. Interface POSIX de manipulation d’un système de fichiers


Informations d’un fichier

Le i-node est representé au niveau programmation par une structure de donnée : stat.

Structure struct stat retournée par


#include <sys/types.h>
#include <sys/stat.h>
int stat(const char* path, struct stat *sb);
int lstat(const char *path, struct stat *sb);

stat() : renvoie les informations sur le fichier désigné par le lien symbolique
Système de fichiers et entrées/sorties
Page 4 sur 9
lstat() : renvoie les informations sur le lien lui-même.

Structure stat : les principaux attributs

st_dev, st_ino // périphérique et numéro du fichier


st_mode // type et droits d’accès
st_nlink // nombre de liens
st_uid, st_gid // propriétaire et son groupe
st_size //taille du fichier (nombre de caractères)
st_atime //date du dernier accès,
st_mtime //date de la dernière modification,
st_ctime //date du dernier changement d’attributs

Identification du nœud dans le système


Afin de localiser le fichier dans le media de stockage (partition et i-nœud) on a besoins des
attributs suivants :

struct stat {
dev_t st_dev;
ino_t st_ino;
...

Pour connaitre le nombre de liens physiques sur le fichier on va consulter l’attribut :

struct stat {
...
nlink_t st_nlink;
...

Type et droits

Type

- Afin de déterminer le type du fichier, il est possible d’utiliser des macros sur le champ st_mode

S_ISREG(m) : Fichier ordinaire


S_ISDIR(m) : Répertoire
S_ISLNK(m): Lien symbolique
S_ISFIFO(m), S_ISBLK(m), S_ISCHR(m), S_ISSOCK(m) etc.

Droits

Décodage des droits d’accès

S_I [RWX] (USR|GRP|OTH)


Et
Système de fichiers et entrées/sorties
Page 5 sur 9
S_IRWX (U|G|O)

Vérification du droit d’accès à un fichier

#include <unistd.h>
int access(const char* path, int a_mode);

droit défini par une combinaison « ou » des macros R_OK, W_OK,


X_OK, et F_OK

exemple:

if (! access(pathname, X_OK))
printf("Fichier exécutable\n");

Positionner les droits d’un fichier

#include <sys/stat.h>
int chmod(const char* path, mode_t mode);

spécification de mode sous forme d’un masque binaire (S_IRUSR, S_IWUSR, S_IXUSR, etc.)

struct stat sbuf;


char *path = "foo/bar";
if (stat(path, &sbuf) >= 0) {
int m = sbuf.st_mode;
if (S_ISREG(m)) {
/* le fichier est un fichier ordinaire*/ …
if (m & (S_IWUSR | S_IWGRP)) {
/* le fichier est inscriptible par le propriétaire ou son groupe*/ …
} } }

Fichiers et répertoires

- Lecture des répertoires

Fonctions de lecture
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *dirpath);
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp);
int rewinddir(DIR *dirp);

Système de fichiers et entrées/sorties


Page 6 sur 9
Exemple : une version rustique de ls

struct dirent *dentry;


DIR *dirp = opendir("foo");
if (dirp == NULL) {
fprintf(stderr, "répertoire inaccessible\n");
exit(EXIT_FAILURE);
}
while((dentry = readdir(dirp)) != 0) {
printf(“%s\n“, dentry->d_name);
}
closedir(dirp);

Manipulations de répertoires
Création/destruction de répertoires

#include <sys/types.h>
#include <sys/stat.h>
int mkdir(const char *path, mode_t mode);
int rmdir(const char *path)
Remarques :
- mode ne doit contenir que des droits d’accès.
- On ne peut détruire qu’un répertoire vide

Exemple
mkdir("foo", S_IRUSR|S_IWUSR|S_IRGRP);

Création et destruction d’entrées dans un répertoire

#include <unistd.h>
int link(const char *oldpath,const char *newpath);
int unlink(const char *path);
int rename(const char *oldpath, const char *newpath);

Ouverture et création de fichiers

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *path, int oflag [, mode_t mode]);

Flag oflag

O_RDONLY, O_WRONLY, O_RDWR mode d’ouverture


O_APPEND place le pointeur d’E/S en fin de fichier
Système de fichiers et entrées/sorties
Page 7 sur 9
O_CREAT crée le fichier s’il n’existe pas
O_EXCL si O_CREAT et si le fichier existe, erreur
O_TRUNC tronquer le fichier s’il existe
etc.

Le troisième argument de open(mode) utilisé seulement si O_CREAT est positionné. Il indique


les droits d’accès au nouveau fichier

S_IRWXU Owner has read, write, and execute permission.


S_IRUSR Owner has read permission.
S_I WUSR Owner has write permission.
S_IXUSR Owner has execute permission.
S_IRWXG Group has read, write, and execute permission.
S_IRGRP Group has read permission.
S_I WGRP Group has write permission.
S_IXGRP Group has execute permission.
S_IRWXO Everyone else has read, write, and execute permission.
S_IROTH Everyone else has read permission.
S_I WOTH Everyone else has write permission.
S_IXOTH Everyone else has execute permission.

Exemple
if (open("foo", O_WRONLY|O_CREAT|O_TRUNC,
S_IRUSR|S_IWUSR|S_IRGRP) < 0) { /* rw- r-- --- */
perror("open");
}

Masque de création de fichier


#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mode);

 mode ne doit contenir que des droits d’accès


 la fonction retourne la valeur précédente du masque
 mode contient les droits que l’on veut dénier
Exemple
oldmask = umask(S_IWGRP|S_IWOTHR);

Lecture/écriture séquentielles
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t n);
ssize_t write(int fd, void *buf, size_t n);
E/S séquentielles
 Le pointeur d ’E/S est avancé du nombre de caractères effectivement transférés
Système de fichiers et entrées/sorties
Page 8 sur 9
 Par défaut, read() est bloquant ; write()peut l’être

Valeur de retour
 Nombre de caractères effectivement transférés
 Pour read(), valeur de retour 0 ⇒fin de fichier

Exemple : une version rustique et partielle de copie de fichiers

char buffer[MAX];
int n;
int fdin = open("foo", O_RDONLY|O_EXCL);
int fdout = open("bar", O_WRONLY|O_TRUNC|O_CREAT, …);
while((n = read(fdin, buffer, MAX)) > 0)
write(fdout, buffer, n);
if (n == 0) /* eof */
else /* n == -1 => erreur */

Accès direct
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

Manipulation directe du pointeur d’E/S

Nouvelle position : whence + offset


- SEEK_SET début du fichier (0)
- SEEK_CUR position courante
- SEEK_EOF fin de fichier

Valeur de retour : nouvelle position absolue (i.e., depuis début du fichier)


Exemples

off_t off = lseek(fd, 0, SEEK_CUR);

Retourne la position absolue courante, sans la modifier

lseek(fd, 0, SEEK_SET);

off_t off = lseek(fd, 100, SEEK_EOF);


Ajoute 100 caractères (nuls) après la fin de fichier
Le fichier doit avoir été ouvert en écriture

Système de fichiers et entrées/sorties


Page 9 sur 9

Vous aimerez peut-être aussi