fcntl | Début | Suivant | Sommaire | Préc.page.lue | Accueil |
NOM | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
SYNOPSIS | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd); int fcntl(int fd, int cmd, long arg); int fcntl(int fd, int cmd, struct flock *lock);
DESCRIPTION | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Dupliquer un descripteur de fichier | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Attributs du descripteur de fichier | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Attribut d'état du fichier | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Les attributs d'état de fichier et leurs sémantiques sont décrits dans la page open(2).
Verrouillages coopératifs | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
struct flock { ... short l_type; /* Type de verrouillage : F_RDLCK, F_WRLCK, F_UNLCK */ short l_whence; /* Interprétation de l_start: SEEK_SET, SEEK_CUR, SEEK_END */ off_t l_start; /* Décalage de début du verrouillage */ off_t l_len; /* Nombre d'octets du verrouillage */ pid_t l_pid; /* PID du processus bloquant notre verrou (F_GETLK seulement) */ ... };Les champs l_whence, l_start, et l_len de cette structure indiquent l'intervalle à verrouiller. l_start est le décalage de début du verrouillage et s'interprète par rapport : au début du fichier (si l_whence vaut SEEK_SET) ; à la position actuelle dans le fichier (si l_whence vaut SEEK_CUR) ; ou la fin du fichier (si l_whence vaut SEEK_END). Dans les deux derniers cas, l_start peut être un nombe négatif, à condition de ne pas indiquer une position avant le début du fichier. l_len est un entier non-négatif (mais voir les NOTES plus bas) indiquant le nombre d'octets à verrouiller. On peut verrouiller des octets après la fin du fichier, mais pas avant son début. Fournir un 0 dans l_len a un sens particulier : verrouiller tous les octets de la position indiquée par l_whence et l_start jusqu'à la fin du fichier, quelque soit sa taille. Le champ l_type peut servir à placer un verrou en lecture (F_RDLCK) ou en écriture (F_WRLCK) sur un fichier. Un nombre quelconque de processus peuvent tenir un verrou en lecture (partagé), sur une région d'un fichier, mais un seul peut avoir un verrou en écriture (exclusif). Un verrou en écriture exclut tous les autres verrous, aussi bien en lecture qu'en écriture. Un processus donné ne peut tenir qu'un seul verrou sur une région d'un fichier, si un nouveau verrou y est appliqué, alors le verrou précédent est converti suivant le nouveau type. Ceci peut entraîner le découpage, la réduction ou l'extension du verrou existant si le nombre d'octets du nouveau verrou ne coïncide pas exactement avec celui de l'ancien.
Verrouillage obligatoire | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Les verrouillages coopératifs ne fonctionnent qu'entre processus qui les utilisent.
Les verrouillages impératifs fonctionnent avec tous les processus.
Si un processus essaie d'effectuer un accès incompatible (par exemple, read(2) ou write(2)) sur la région d'un fichier qui a un verrouillage impératif incompatible, le résultat dépendra de si l'attribut O_NONBLOCK est activé pour cette description de fichier ouvert. Si l'attribut O_NONBLOCK n'est pas activé, l'appell système bloquera jusqu'à ce que le verrou soit supprimé ou converti dans un mode compatible avec l'accès. Si l'attribut O_NONBLOCK est activé, l'appel système échouera avec l'erreur EAGAIN ou EWOULDBLOCK.
Pour utiliser des verrous impératifs, ce type de verrouillage doit être activé sur le système de fichiers contenant le fichier à verrouiller et sur le fichier lui-même. Le verrouillage impératif est activé sur un système de fichiers en utilisant l'option « -o mand » de mount(8) ou l'attribut MS_MANDLOCK de mount(2). Le verrouillage impératif est activé sur un fichier en désactivant la permission d'exécution du groupe et en activant le bit de permission Set-GID (voir chmod(1) et chmod(2)).
L'implémentation Linux des verrouillages obligatoires n'est pas fiable. Voir BOGUES plus loin.
Gestion des signaux | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Si vous définissez l'attribut O_ASYNC sur un descripteur de fichier en utilisant la commande F_SETFL de fcntl()), un signal SIGIO est envoyé dès que l'entrée ou la sortie sont possibles sur ce descripteur. F_SETSIG peut être utilisé pour obtenir la délivrance d'un signal autre que SIGIO. Si cette vérification de permission échoue, le signal est silencieusement abandonné.
L'envoi d'un signal au processus (groupe) propriétaire spécifié par F_SETOWN est sujet aux mêmes vérifications de permissions comme cela est décrit pour kill(2), où le processus envoyant est celui qui utilise F_SETOWN (mais voir BOGUES plus loin).
Si le descripteur de fichier fd fait référence à une socket, F_SETOWN permet également la réception de signaux SIGURG lorsque des données hors-bande arrivent sur la socket. (SIGURG est émis dans toutes les situations où l'appel select(2) aurait indiqué que la socket est dans une « situation exceptionnelle »).
Si une valeur non nulle est fournie à F_SETSIG dans un processus multi-thread en cours d'exécution avec un bibliothèque de threads qui supportent les groupes de threads (par exemple NPTL), alors une valeur positive fournie à F_SETOWN à une signification différente : plutôt que d'être un PID indentifiant un processus entier, c'est un ID de thread identifiant un thread spécifique à l'intérieur d'un processus. Par conséquent, il peut être nécessaire de passer à F_SETOWN le résultat de gettid(2) plutôt que celui de getpid(2) pour rendre les résultats sensibles lorsque F_SETSIG est utilisé. (Dans les actuelles implémentations de threads Linux, le TID d'un thread principal est le même que son PID. Cela signifie qu'un programme simple thread peut indifféremment utiliser gettid(2) ou getpid(2) dans ce scenario.) Notez toutefois que les instructions dans ce paragraphe ne s'appliquent pas au signal SIGURG généré pour des données hors-bande sur une socket : ce signal est toujours envoyé soit à un processus, soit à un groupe de processus, suivant la valeur donnée à F_SETOWN. Notez également que Linux impose une limite sur le nombre de signaux temps réel qui peuvent être mis en file d'attente dans un processus (voir getrlimit(2) et signal(7)). Si cette limite est atteinte, le noyau revient à la délivrance de SIGIO et ce signal est délivré au processus entier plutôt qu'à un thread spécifique.
De plus, passer une valeur non nulle à F_SETSIG modifie la réception du signal d'un processus entier à un thread spécifique du processus. Voir la desciption de F_SETOWN pour plus de détails.
En utilisant F_SETDIG avec une valeur non-nulle, et en configurant SA_SIGINFO pour le gestionnaire (voir sigaction(2)), des informations supplémentaires sur les événements d'entrées-sorties sont fournies au gestionnaire à travers une structure siginfo_t. Si le champ si_code indique que la source est SI_SIGIO, le champ si_fd fournit le descripteur du fichier concerné par l'événement. Sinon il n'y a pas d'indication du descripteur en attente, et il faut utiliser le mécanisme habituel (select(2), poll(2), read(2) avec O_NONBLOCK configuré etc.) pour déterminer quels descripteurs sont disponibles pour les entrées-sorties.
En sélectionnant un signal temps réel (valeur >= SIGRTMIN), de multiples événements d'entrées-sorties peuvent être mémorisés avec le même numéro. Des informations supplémentaires sont disponibles, comme ci-dessus, si SA_SIGINFO est configuré pour le gestionnaire.
En utilisant ces mécanismes, un programme peut implémenter des entrées-sorties totalement asynchrones, la plupart du temps sans avoir besoin d'invoquer select(2) ou poll(2).
L'utilisation de O_ASYNC, F_GETOWN, est spécifique BSD et Linux. F_GETSIG et F_SETSIG sont spécifiques à Linux. POSIX disposent d'entrées-sorties asynchrones et de la structure aio_sigevent pour effectuer la même chose. Ceci est également disponible sous Linux dans la glibc.
Baux | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Lorsqu'un processus (le « casseur de bail » appelle open(2) ou truncate(2) en conflit avec un bail établi par F_SETLEASE, l'appel système est bloqué par le noyau et le noyau avertit le processus tenant le bail par l'envoi d'un signal (SIGIO par défaut). Le tenant du bail doit répondre à ce signal en effectuant tout le nettoyage nécessaire pour que le fichier soit accessible par un autre processus (p.ex. en vidant des tampons internes) et en supprimant ou déclassant son bail. Un bail est supprimé en appelant la commande F_SETLEASE avec arg valant F_UNLCK. Si le tenant du bail tient actuellement un bail en écriture sur le fichier et que le casseur de bail ouvre le fichier en lecture, cela est suffisant pour que le tenant du bail déclasse le bail en un bail en lecture. Cela est effectué en appelant la commande F_SETLEASE avec arg valant F_RDLCK.
Si le détenteur du bail n'arrive pas à le déclasser ou le supprimer avant le nombre de secondes indiqué dans /proc/sys/fs/lease-break-time alors le noyau supprimera ou déclassera de force le bail du processus qui le tient.
Dès que le bail a été, de gré ou de force, résilié ou déclassé et en supposant que le casseur de bail n'a pas débloqué son appel système, le noyau permet à ce dernier de se dérouler.
Si un appel open(2) ou truncate(2) bloqué, effectué par le casseur de bail, est interrompu par un gestionnaire de signal, l'appel système échoue avec l'erreur EINTR, mais les autres étapes se dérouleront comme décrit plus haut. Si le casseur de bail est tué par un signal alors qu'il est bloqué dans open(2) ou truncate(2), les autres étapes se dérouleront comme décrit plus haut. Si le casseur de bail spécifie l'attribut O_NONBLOCK lorsqu'il appelle open(2), l'appel échouera immédiatemment avec l'erreur EWOULDBLOCK, mais les autres étapes se dérouleront comme décrit plus haut.
Le signal de notification par défaut pour le tenant du bail est SIGIO, mais on peut le modifier avec la commande F_SETSIG de la fonction fcntl (). Si une commande F_SETSIG est réalisée (même pour SIGIO), et si le gestionnaire de signal est installé avec SA_SIGINFO, alors il recevra une structure siginfo_t en second argument, et le champ si_fd contiendra le descripteur de fichier du bail où il y a eu une tentative d'accès par un autre processus. (Ceci sert si le processus tient des bails sur plusieurs fichiers.)
Notification de modification de fichier et de répertoire (dnotify) | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Les notifications de répertoire sont habituellement uniques, et l'application doit ré-enregistrer une demande pour les notifications ultérieures. Inversement, si DN_MULTISHOT est incluse dans arg, les notifications resteront en effet jusqu'à une demande explicite de suppression. Une série de F_NOTIFY sont cumulés, les événements décrits dans arg étant ajoutés à l'ensemble des événements déjà surveillés. Pour supprimer les notifications de tous les événements, il faut invoquer F_NOTIFY avec arg valant 0.
La notification se produit par l'occurrence d'un signal. Le signal par défaut est SIGIO, mais on peut le changer avec la commande F_SETSIG de fcntl(). Dans ce cas, le gestionnaire de signal reçoit une structure siginfo_t en second argument (si le gestionnaire a été installé avec SA_SIGINFO) dont le champ si_fd contient le descripteur du fichier qui a déclenché la notification (utile pour superviser plusieurs répertoires).
En outre, avec DN_MULTISHOT, un signal temps réel devrait être utilisé pour la notification pour pouvoir empiler les notifications successives.
NOTE : Les nouvelles applications devraient penser à utiliser l'interface inotify (disponible depuis le noyau 2.6.13), qui fournit une interface supérieure pour l'obtention de notifications des événement du système de fichier. Voir inotify(7).
VALEUR RENVOYÉE | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
En cas d'échec -1 est renvoyé, auquel cas errno contient le code d'erreur.
ERREURS | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
CONFORMITÉ | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
F_GETSIG, F_SETSIG, F_NOTIFY, F_GETLEASE et F_SETLEASE sont spécifiques à Linux. (Définissez la macro _GNU_SOURCE pour avoir ces définitions).
NOTES | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Depuis le noyau 2.0, il n'y a pas d'interaction entre les verrous placés par flock(2) et ceux de fcntl().
POSIX.1-2001 permet à l_len d'être négative (et si c'est le cas, l'intervalle décrivant le verrou couvre les octets l_start+l_len jusqu'à l_start-1 inclus). Ceci est supporté par Linux depuis les versions 2.4.21 et 2.5.49.
Plusieurs systèmes ont d'autres champs dans struct flock comme, par exemple, l_sysid. Clairement, l_pid seul ne sera pas très utile si le processus tenant le verrou s'exécute sur une autre machine.
BOGUES | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Dans Linux 2.4 et précédents, il y a un bogue qui apparait lorsqu'un
processus non privilégié utilise
F_SETOWN
pour spécifier le propriétaire d'un descripteur de fichier socket
comme un processus (groupe) autre que l'appelant.
Dans ce cas,
fcntl()
peut retourner -1 avec
errno
remplie avec
EPERM,
même lorsque l'appelant a effectivement le droit d'envoyer des signaux au
processus (groupe) propriétaire.
En dépit de ce retour d'erreur, le propriétaire du descripteur de fichier
est configuré et les signaux seront bien envoyés aux propriétaires.
L'implémentation du verrouillage obligatoire dans toutes les versions connues de Linux est sujet à des conditions de concurrence qui la rende non fiable : The implementation of mandatory locking in all known versions of Linux is subject to races which render it unreliable: un appel write(2) qui chevauche un verrou peut modifier les données après que le verrouillage obligatoire ait été acquis ; un appel read(2) qui chevauche un verrou peut détecter des modifications sur des données qui ont été faites seulement après qu'un verrou en écriture ait été acquis. Des conditions de concurrence similaires existent entre les verrous obligatoires et mmap(2). Il est donc déconseillé de faire confiance au verrouillage obligatoire.
VOIR AUSSI | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Voir aussi les fichiers Documentation/locks.txt, Documentation/mandatory.txt et Documentation/dnotify.txt dans les sources du noyau.
TRADUCTION | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 11 octobre 1996 et révisée le 22 avril 2008.
L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 2 fcntl ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.
Sommaire | Début | Suivant | Sommaire | Préc.page.lue | Accueil |
Table des mots clés | Début | Suivant | Sommaire | Préc.page.lue | Accueil |
EACCESS ou EAGAIN | ERREURS |
EAGAIN | ERREURS |
EBADF | ERREURS |
EDEADLK | ERREURS |
EFAULT | ERREURS |
EINTR | ERREURS |
EINVAL | ERREURS |
EMFILE | ERREURS |
ENOLCK | ERREURS |
EPERM | ERREURS |
F_DUPFD | VALEUR RENVOYÉE |
F_DUPFD_CLOEXEC (depuis Linux 2.6.24) | Dupliquer un descripteur de fichier |
F_GETFD | VALEUR RENVOYÉE |
F_GETFL | VALEUR RENVOYÉE |
F_GETLEASE | VALEUR RENVOYÉE |
F_GETLK | Verrouillages coopératifs |
F_GETOWN | VALEUR RENVOYÉE |
F_GETSIG | VALEUR RENVOYÉE |
F_NOTIFY | Notification de modification de fichier et de répertoire (dnotify) |
F_SETFD | Attributs du descripteur de fichier |
F_SETFL | Attribut d'état du fichier |
F_SETLEASE | Baux |
F_SETLK | Verrouillages coopératifs |
F_SETLKW | Verrouillages coopératifs |
F_SETOWN | Gestion des signaux |
F_SETSIG | Gestion des signaux |