Types
struct flockFonctions
struct pollfd
struct stat
chmod()
close()
creat()
dup()
dup2()
fchmod()
fcntl()
flock()
fstat()
getdtablesize()
lseek()
mknod()
open()
pipe()
poll()
read()
select()
stat()
umask()
unlink()
write()
fchmod et chmod - modifient les droits d'accès d'un fichier.Syntaxe
#include <sys/stat.h> // contient le prototype
de chmod() et fchmod()
int chmod (const char * path, mode_t mode);
|
Description
Les fonctions fchmod() et chmod() modifient les droits d'accès à un fichier désigné soit par son descripteur filedes, soit par son chemin d'accès path.
Le masque mode (ensemble de bits) remplace l'ancien masque des droits d'accès au fichier de chemin d'accès path.
Certains utilisateurs préfèrent utiliser les constantes symboliques définies dans le fichier
/usr/include/linux/stat.h
, plutôt que les valeurs numériques directes (plus grande lisibilité et plus grande portabilité).
Ainsi, les deux lignes ci-dessous sont équivalentes :
chmod (mon_fich, 0764); |
et
chmod (mon_fich, S_IRWXU | S_IWGRP | S_IRGRP | S_IROTH); |
Valeur retournée
Les fonctions chmod() et fchmod() renvoient la valeur 0 en cas de succès.
Diagnostic d'erreur
Les fonctions chmod() et fchmod() renvoient -1 en cas d'erreur et positionnent la variable globale errno.
close - ferme un fichier.Syntaxe
#include <unistd.h> // contient le prototype de
close()
int close (int fd); |
Description
La fonction close() ferme le fichier de file descriptor fd.
Valeur retournée
La fonction close() renvoie la valeur 0 en cas de succès. (voir le déverrouillage des fichiers provoqué par la fonction close()).
Diagnostic d'erreur
La fonction close() renvoie -1 en cas d'erreur et positionne la variable globale errno.
creat - ouvre un fichier après l'avoir éventuellement créé.Syntaxe
#include <fcntl.h> // contient le prototype de
creat()
int creat (const char *path, mode_t mode); |
Description
La fonction creat() ouvre en écriture le fichier de chemin d'accès path, après l'avoir créé s'il n'existait pas. S'il existait auparavant, sa longueur est tronquée à 0. Si le fichier existait déjà, ses droits d'accès ne sont pas modifiés. Sinon, les droits d'accès du nouveau fichier sont calculés à partir du paramètre mode et des restrictions courantes de droits par défaut (que nous noterons ici masque), positionnés et donnés par la fonction umask(). Le calcul est le suivant :
nouveaux_droits = mode & ~masque;
Par exemple, si mode vaut 0666 et si masque vaut 026, alors les droits obtenus seront 0640, soit rw-r-----. Rappelons en effet que les bits positionnés (à 1) de masque correspondent à des protections, donc des interdits.
Comme pour la fonction chmod(), on peut préférer utiliser les constantes symboliques définies dans le fichier /usr/include/sys/stat.h , plutôt que les valeurs numériques directes.
Remarque : la fonction creat() ne peut être utilisée pour créer un fichier spécial.
Valeur retournée
La fonction creat() renvoie un descripteur de fichier (file descriptor) en cas de succès.
Diagnostic d'erreur
La fonction creat() renvoie -1 en cas d'erreur et positionne la variable globale errno.
Jdup - duplique un descripteur de fichier (file descriptor).Syntaxe
#include <unistd.h> //
permet d'accéder au prototype de dup()
int dup (int oldfd); |
Description
La fonction dup() renvoie un nouveau descripteur sur le fichier initialement pointé par le descripteur oldfd. Ce nouveau descripteur est l'entier positif ou nul le plus petit possible. Cette fonction est essentiellement utilisée pour détourner des flux (en particulier pour rediriger les entrées/sorties). Elle est souvent utilisée couplée avec l'utilisation de pipes ou de sockets.
Valeur retournée
La fonction dup() renvoie un entier positif ou nul en cas de succès.
Diagnostic d'erreur
La fonction dup() renvoie -1 en cas d'erreur (oldfd inexistant). La variable globale errno est positionnée.
dup2 - duplique un descripteur de fichier (file descriptor).Syntaxe
#include <unistd.h> //
permet d'accéder au prototype de dup2()
int dup2 (int oldfd, int newfd); |
Description
Après appel de la fonction dup2(), le descripteur newfd pointe sur le même fichier que le descripteur oldfd. Si le descripteur newfd correspondait à un fichier ouvert avant l'appel, celui-ci est fermé automatiquement avant d'être réaffecté.
Valeur retournée
La fonction dup2() renvoie le nouveau descripteur (newfd) en cas de succès.
Diagnostic d'erreur
La fonction dup2() renvoie -1 en cas d'erreur (oldfd inexistant). La variable globale errno est positionnée.
fcntl – effectue des opérations de contrôle sur un fichier ouvert.Syntaxe
#include <fcntl.h> // contient le prototype de
fcntl()
int fcntl (int filedes, int request);
[1]
|
Description
La fonction fcntl() effectue sur le fichier ouvert désigné par le file descriptor filedes le traitement request en utilisant éventuellement les informations complémentaires (paramètres de request) dans argument.
L'interprétation de argument dépend de la valeur de request. Les requêtes possibles sont les suivantes :
F_DUPFD | utilisée avec cette requête, la fonction fcntl() a le même comportement que la fonction dup() |
F_GETFD, F_SETFD | utilisées en liaison avec la fonction système exec..().
En donnant au paramètre request la valeur F_SETFD et au paramètre argument la valeur FD_CLOEXEC
[4]
, le fichier de file descriptor filedes est refermé lors de l'appel de la fonction exec...().
utilisée avec F_GETFD, la fonction fcntl() renvoie l'état du flag Close-on-exec : si le bit de plus faible poids (bit 0) est nul, le flag n'est pas positionné. |
F_GETFL | la fonction fcntl() renvoie les bits d'état (file status flags) et les modes d'accès (file access modes) du fichier désigné par le file descriptor filedes. Différentes constantes du fichier fcntl.h permettent d'accéder à ces différents bits.
Les bits de mode d'accès indiquent si le fichier a été ouvert en lecture seule, en écriture seule ou en lecture/écriture. Les bits d'état donnent des indications au système d'exploitation sur la façon dont doivent se dérouler les opérations d'entrées/sorties. Certains n'ont de sens que pour des fichiers particuliers (par exemple les sockets). Le positionnement des bits d'état permet d'ajouter les propriétés suivantes :
|
F_SETFL | la fonction fcntl() ne permet pas de modifier les modes d'accès du fichier désigné par le file descriptor filedes. Parmi ses bits d'état (file status flags), seuls peuvent être modifiés ceux qui ne concernent pas la synchronisation. |
F_GETOWN, F_SETOWN | utilisables seulement avec les sockets (voir cours/TP réseaux) |
F_GETLK, F_SETLK, F_SETLKW | concerne le (dé)verrouillage des fichiers : voi ci-dessous. |
Parmi les trois prototypes présentés plus haut, seul celui-ci permet la manipulation des verrous sur un fichier (voir aussi la fonction flock()).
Le paramètre argument est un
pointeur sur une structure qui décrit les caractéristiques
du verrouillage demandé :
struct flock
{ short l_type; short l_whence; off_t l_start; off_t l_len; pid_t l_pid; }; |
#define F_RDLCK 0 /* Read (shared) lock
*/
#define F_WRLCK 1 /* Write (exclusive) lock */ #define F_UNLCK 2 /* Remove lock */ |
Les requêtes request possibles sont les suivantes :
La signification de la valeur de retour de la fonction fcntl() dépend de la valeur du paramètre request (voir en détail dans le man de la fonction).
Diagnostic d'erreur
La fonction fcntl() renvoie -1 en cas d'erreur et positionne la variable globale errno (voir en détail dans le man de la fonction).
flock – effectue une opération de (dé)verrouillage sur un fichier ouvert (voir aussi la fonction fcntl()).Syntaxe
#include <sys/file.h> // contient le
prototype de flock()
int flock (int filedes, int operation); |
Description
Le paramètre operation peut prendre
l'une des quatre valeurs suivantes, suivant la nature de l'opération
désirée :
include <sys/file.h>
#define LOCK_SH 1 /* shared lock
*/
|
Combinée avec les opérations LOCK_SH ou LOCK_EX (par l'opérateur |), l'opération LOCK_NB rend la fonction flock() non bloquante, qui renvoie alors la valeur –1 et positionne la variable globale errno à EAGAIN.
Valeur retournée
La fonction flock() renvoie la valeur 0 en cas de succès.
Diagnostic d'erreur
La fonction flock()renvoie -1 en cas d'erreur et positionne la variable globale errno.
fstat et stat - statistiques sur les fichiers.Syntaxe
#include <sys/stat.h> // contient les prototypes
de stat() et fstat()
int stat (const char *path, struct stat *buffer);
|
Description
Les fonctions fstat() et stat() récupèrent des informations statistiques d'un fichier désigné soit par son descripteur filedes, soit par son chemin d'accès path.
Ces informations sont chargées dans une variable
buffer
ayant la structure stat :
Le champ st_mode contient les droits du fichier, qui peuvent être analysées au moyen des constantes définies dans le fichier /usr/include/linux/stat.h (voir types de fichiers).
Valeur retournée
Les fonctions fstat() et stat() renvoient la valeur 0 en cas de succès.
Diagnostic d'erreur
Les fonctions fstat() et stat() renvoient -1 en cas d'erreur et positionnent la variable globale errno.
getdtablesize - renvoie le nombre maximal de fichiers ouvertsSyntaxe
#include <unistd.h> // contient le prototype de getdtablesize()
int getdtablesize (void); |
Valeur retournée
La fonction getdtablesize() renvoie le nombre maximal de fichiers que peut ouvrir un processus. Cela correspond à la taille de la table des file descriptors.
Diagnostic d'erreur
La fonction getdtablesize() ne peut échouer.
lseek - accès direct dans un fichier.Syntaxe
#include <unistd.h> // contient le prototype de lseek
()
off_t lseek (int fd, off_t offset, int whence); |
Description
La fonction lseek() permet d'ajouter algébriquement offset octets au pointeur courant (pointeur vers le prochain octet qui va être lu ou écrit) du fichier de descripteur fd à partir :
- du début du fichier si whence == SEEK_SETLe paramètre offset peut prendre n'importe quelle valeur à condition que le pointeur courant ne devienne pas négatif. Une valeur négative de offset associé à la valeur SEEK_END de whence permet de lire un fichier à l'envers. Si une valeur > 1 de offset est utilisée en association avec SEEK_END, les intervalles non écrits du fichier sont remplis de zéros.
- de la position courante si whence == SEEK_CUR
- de la fin du fichier si whence == SEEK_END
Attention : le premier octet du fichier est de rang 0.
Remarque : la fonction lseek() ne peut être appliquée à un pipe une FIFO (pipe anonyme) ou une socket.
Valeur retournée
En cas de succès, la fonction lseek() renvoie la position courante du pointeur d'enregistrement du fichier après sa modification.
Diagnostic d'erreur
La fonction lseek() renvoie la valeur -1 en cas d'erreur et positionne la variable globale errno.
mknod - crée un noeud du système de fichiers.Syntaxe
#include <sys/types.h> // contient la définition de mode_t et dev_t
#include <unistd.h> // contient le profil de mknod() int mknod (const char * pathname, mode_t mode, dev_t dev); |
Description
La fonction mknod() crée un noeud du système de fichiers (fichier, fichier spécial de périphérique ou pipe) appelé pathname, avec les attributs mode et dev.
Le paramètre mode définit à la fois les permissions d'utilisation et le type de noeud à créer. C'est une combinaison par OU binaire ( | ) entre les permissions d'accès pour le nouveau noeud et l'un des types de noeuds ci-dessous (définis dans <fcntl.h>) :
Comme pour les fonctions open() et creat(), les permissions sont modifiées par le umask du processus : les permissions effectivement écrites sont (mode & ~umask).
On peut également utiliser 0 pour créer un fichier normal.
Si le noeud est de type S_IFCHR or S_IFBLK, alors dev doit spécifier des numéros correspondant au périphérique associé, pour les autres types de noeuds, dev est ignoré.
Remarque : la fonction lseek() ne peut être appliquée à un FIFO (pipe anonyme).
Valeur retournée
La fonction mknod() retourne 0 en cas de succès.
Diagnostic d'erreur
La fonction mknod() renvoie -1 en cas d'erreur et positionne la variable globale errno. Une erreur est générée par exemple lorsque le noeud existe déjà, errno vaut alors EEXIST.
open - ouvre un fichier.Syntaxe
#include <fcntl.h> // contient le prototype de open ()
int open (const char *path, int oflag);
[2]
|
Description
La fonction open() ouvre le fichier de chemin d'accès path, en utilisant les indicateurs du paramètre oflag. Le paramètre oflag regroupe les bits indicateurs d'accès et les bits d'état du fichier. Si un de ces indicateurs est O_CREAT (créer le fichier s'il n'existe pas déjà), un troisième paramètre mode de type mode_t doit être utilisé. Son utilisation est identique à celle du même paramètre de la fonction creat().
Les indicateurs du paramètre oflag sont positionnés en utilisant l'opérateur | (ou) entre les valeurs parmi celles-ci :
O_CREAT | création du fichier s'il n'existe pas |
O_TRUNC | tronque à 0 la taille du fichier (purge) s'il est ouvert en lecture/écriture ou en écriture seulement |
O_EXCL | provoque une erreur si le fichier existe déjà et si O_CREAT est aussi positionné |
O_NOCTTY | concerne les "fichiers" terminaux; non étudié ici. |
O_RDONLY | ouverture en lecture seulement (valeur par défaut) |
O_WRONLY | ouverture en écriture seulement |
O_RDWR | ouverture en lecture et écriture |
Les deux appels ci-dessous sont équivalents :
creat (path, mode);
open (path, O_WRONLY | O_CREAT | O_TRUNC, mode); |
Valeur retournée
La fonction open() renvoie la valeur du descripteur de fichier correspondant au nom de fichier path.
Diagnostic d'erreur
La fonction open() renvoie -1 en cas d'erreur et positionne la variable globale errno.
pipe - crée un canal de communication.Syntaxe
#include <unistd.h> // contient le prototype de pipe ()
int pipe (int pfd[2]); [5] |
Description
La fonction pipe() crée un tube (pipe en anglais) et initialise le vecteur pfd avec deux descripteurs analogues à des descripteurs de fichiers, les deux plus petites valeurs au moment de l'appel. L'un des descripteurs, pfd[0], permet de lire dans le pipe, l'autre, pfd[1], permet d'y écrire. Le pipe se comporte comme une file FIFO : les données sont lues dans l'ordre dans lequel elles ont été écrites. Ce moyen est utilisable pour échanger des informations entre des processus parents (on rappelle que les processus fils d'un processus héritent des descripteurs du père et partagent les fichiers si ceux-ci ont été ouverts avant l'appel à la fonction fork()). Les deux descripteurs donnant accès au même support, un processus peut lire dans un pipe les données qu'il y a écrites préalablement, si aucun autre processus ne les a prélevées entre-temps. Une communication bidirectionnelle entre deux processus ne peut donc être obtenue qu'en ouvrant deux pipes qui seront utilisés chacun dans un seul sens (le premier en lecture, le second en écriture pour un processus, et le contraire pour l'autre processus) ou en établissant un protocole de communication (comme avec des walkies-talkies).
Les appels système read(), write(), close(), fstat(), fcntl(), dup() et dup2() peuvent être utilisés avec les pipes comme avec les fichiers. Ils provoquent cependant des actions légèrement différentes
Remarque : la fonction lseek() ne peut être appliquée à un pipe.
Valeur retournée
La fonction pipe() renvoie 0 si l'opération s'est bien déroulée.
Diagnostic d'erreur
La fonction pipe() renvoie -1 en cas d'erreur et la variable globale errno est positionnée.
poll - attend un événement concernant un descripteur de fichier.Syntaxe
#include <sys/poll.h> // contient la définition de struct pollfd
// et le profil de poll() int poll (struct pollfd *ufds, unsigned int nfds, int delai); |
Description
La fonction poll() est une variation sur le thème de
select().
Elle utilise un vecteur de nfds structures du type
struct pollfd
{ int fd; /* Descripteur de fichier */ short events; /* Evénements attendus */ short revents; /* Evénements détectés */ }; |
La structure polldf est formée de trois champs :
Si aucun événement attendu (ni aucune erreur) ne s'est déjà produit, le noyau attend leur occurence pendant delai millisecondes.
Les deux masques sont construits par composition (opérateur booléen OU |) de plusieurs constantes (bits) qui décrivent les événements.
Les trois valeurs de constantes qui nous intéressent sont définis dans <sys/poll.h> :
#define POLLIN 0x0001 /* Données disponibles en lecture */
#define POLLPRI 0x0002 /* Données urgentes disponibles */ #define POLLOUT 0x0004 /* Une écriture bloquerait */ |
Valeur retournée
La fonction poll() renvoie une valeur positive représentant le nombre de structures ayant un champ revents non-nul, c'est-à-dire le nombre de structures pour lesquels un événement attendu s'est produit. Une valeur de retour nulle indique un dépassement du délai d'attente.
Diagnostic d'erreur
La fonction poll() retourne -1 en cas d'erreur et positionne la variable globale errno.
read - lit un certain nombre d'octets dans un fichier.Syntaxe
#include <unistd.h> // contient le prototype de read()
ssize_t read (int filedes, void * buffer, size_t nbytes); |
Description
Seule la lecture sur fichier disque est envisagée. Nous étudierons ultérieurement les lectures sur pipes et sockets. La fonction read() essaie de lire nbytes octets dans le fichier de descripteur filedes, qu'elle range à partir de l'adresse buffer. Elle renvoie le nombre d'octets effectivement lus.
Remarque : le résultat de la lecture n'est pas spécifié si nbytes est supérieur à la constante SSIZE_MAX définie dans <bits/posix1_lim.h>
Valeur retournée
La fonction read() renvoie le nombre d'octets effectivement lus. Si le nombre d'octets lus est 0, c'est que la fin de fichier est atteinte.
Diagnostic d'erreur
La fonction read() renvoie –1 en cas d'erreur et positionne la variable globale errno.
select - multiplexage d'E/S synchrones.Syntaxe
#include <sys/time.h> // permet d'atteindre indirectement
// le prototype de select() - fichier <sys/select.h> // les types fd_set et struct timeval - fichier <bits/time.h> int select (int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval *timeout); |
Description
La fonction select() attend un événement sur au moins un des descripteurs de fichiers positionnés dans l'un des masques readfds, writefds ou exceptfds. Si les pointeurs passés en paramètres sont nuls, les masques correspondants sont ignorés par la fonction select(). Le paramètre nfds indique le nombre maximal de descripteurs contenus dans les masques.
A l'appel de la fonction select() :
Sous Linux, si un événement attendu est arrivé sur un descripteur, timeout pointe sur une structure qui contient le délai restant dans le sablier. Attention cependant à la non portabilité de cette implémentation.
Les quatre macros suivantes (définies dans <sys/select.h> et aussi accessibles indirectement par <sys/time.h>) permettent de manipuler les bits d'un masque fdset de type fd_set :
...
/* fd_set for select and pselect. */ typedef struct { #ifdef __USE_XOPEN __fd_mask fds_bits [__FD_SETSIZE / __NFDBITS]; # define __FDS_BITS(set) ((set)->fds_bits) #else __fd_mask __fds_bits [__FD_SETSIZE / __NFDBITS]; # define __FDS_BITS(set) ((set)->__fds_bits) #endif } __fd_set; ... |
Valeur retournée
La fonction select() renvoie le nombre total d'événements arrivés sur l'ensemble des descripteurs positionnés dans les trois masques. Elle renvoie 0 si le délai est arrivé à expiration avant l'arrivée d'un événement.
Diagnostic d'erreur
La fonction select() renvoie -1 en cas d'erreur. La variable globale errno est positionné
umask – modifie les valeurs par défaut des droits d'accès aux fichiers.Syntaxe
#include <sys/stat.h> // contient le prototype de umask()
mode_t umask (mode_t cmask); |
Description
La fonction umask() positionne les bits de masquage des droits d'accès des fichiers. Les valeurs des bits sont les mêmes que celles utilisées dans la fonction chmod() : voir le fichier <linux/stat.h>. Il faut remarque que si un bit est positionné, il empêche que le droit correspondant soit donné à un fichier (en fait, le bit correspondant du fichier est mis à 0).
Valeur retournée
La fonction umask() renvoie la valeur du
masque avant modification. Ainsi, il faut deux appels pour récupérer
la valeur du masque sans la modifier :
mode_t masque = 0777;
umask (masque = umask (masque)); |
Diagnostic d'erreur Aucun.
unlink - supprime un lien d'un fichier.Syntaxe
#include <unistd.h> // contient le prototype de unlink
()
int unlink (const char *path); |
Description
La fonction unlink() supprime du répertoire
l'entrée correspondant au fichier indiqué, et réduit
le compteur de liens de l'i-noeud d'une unité. Si le compteur
de liens est nul, le fichier sera supprimé du file system
(rendu à la liste libre des blocs) lorsque le processus sera terminé.
Cette propriété peut être utilisée pour créer
des fichiers temporaires :
fd = creat ("temp", S_IRWXU);
unlink ("temp"); |
Valeur retournée
La fonction unlink() renvoie la valeur 0 en cas de succès.
Diagnostic d'erreur
La fonction unlink() renvoie -1 en cas d'erreur et positionne la variable globale errno.
write - écrit un certain nombre d'octets dans un fichier.Syntaxe
#include <unistd.h> // contient le prototype de write
()
ssize_t write (int filedes, const void * buffer, size_t nbytes); |
Description
Seule l'écriture sur fichier disque est envisagée. Nous étudierons ultérieurement les écritures sur pipes et sockets. La fonction write() essaie d'écrire nbytes octets dans le fichier de descripteur filedes, à partir de l'adresse buffer. Elle renvoie le nombre d'octets effectivement écrits. Pour un fichier disque, si le nombre d'octets effectivement écrits est inférieur à nbytes, cela doit être considéré comme une erreur (en fait c'est impossible!).
Valeur retournée
La fonction write() renvoie le nombre d'octets effectivement écrits.
Diagnostic d'erreur
La fonction write() renvoie -1
en cas d'erreur et positionne la variable globale errno.
int fcntl (int fd, int cmd, ...);
Il faut rappeler que, en cas de nombre de paramètres variable, les compilateurs C/C++ ne peuvent plus vérifier le type des paramètres correspondants. Il est donc préférable d'utiliser la possibilité offerte par le C++ de surcharger une fonction pour lui donner des profils différents. Il faut aussi remarquer que le man de fcntl() en français n'indique que l'existence des deux premiers profils, contrairement au xman en anglais ==> à qui se fier ?!!!
[2] Comme pour la fonction fcntl(), la fonction open() n'a en réalité qu'un seul prototype, qui est le suivant :
int open (const char *path, int oflag, ...);
[3]
La macro PIPE_BUF est définie dans le fichier /usr/include/linux/limits.h et a pour valeur 4096.
Il existe aussi une autre macro, _POSIX_PIPE_BUF, définie dans le fichier /usr/include/bits/posix1_lim.h, qui a pour valeur 512. Les merveilles de la normalisation ...
[4] La macro FD_CLOEXEC est définie dans les fichiers /usr/include/bits/fcntl.h et /usr/include/asm/fcntl.h et est accessible à travers /usr/include/fcntl.h. Le man de fcntl() en français n'indique pas l'existence de cette macro, contrairement au man en anglais, obtenu par la commande xman
[5] Rappel : le paramètre effectif de la fonction pipe() est l'adresse à laquelle le système rangera les descripteurs de pipe (paramètre résultat). Afin de rappeler à l'utilisateur qu'il doit y avoir la place de ranger deux descripteurs, le profil indique : int pfd [2] mais la valeur entre [] est purement indicative. Les déclarations suivantes seraient tout aussi correctes, quoique moins lisibles : int pfd [] ou int * pfd.