NOM¶
fcntl - Manipuler un descripteur de fichier
SYNOPSIS¶
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
DESCRIPTION¶
fcntl() permet de se livrer à diverses opérations sur le
descripteur de fichier
fd. L'opération en question est
déterminée par la valeur de l'argument
cmd.
fcntl() prend un troisième paramètre optionnel. La
nécessité de fournir ce paramètre dépend de
cmd. le paramètre doit être du type indiqué entre
parenthèses après chaque nom de commande
cmd (dans la
plupart des cas, le type requis est un
int, et le paramètre est
identifié en utilisant le nom
arg), ou
void est
indiqué si le paramètre n'est pas nécessaire.
Dupliquer un descripteur de fichier¶
- F_DUPFD (int)
- Trouver le plus petit numéro de descripteur libre supérieur
ou égal à arg et le transformer en copie de
fd. Ceci est différent de dup2(2), qui utilise
exactement le descripteur transmis.
- En cas de réussite, le nouveau descripteur est renvoyé.
- Consultez dup(2) pour plus d'informations.
- F_DUPFD_CLOEXEC (int ; depuis Linux 2.6.24)
- Comme pour F_DUPFD, mais positionne en plus l'attribut
« close-on-exec » pour le descripteur
dupliqué. Indiquer cet attribut permet d'éviter une
opération F_SETFD de fcntl() supplémentaire
pour positionner l'attribut FD_CLOEXEC. Pour une explication sur ce
en quoi cet attribut est utile, consultez la description de
O_CLOEXEC dans open(2).
Attributs du descripteur de fichier¶
Les commandes suivantes manipulent les attributs associés à un
descripteur de fichier. Actuellement, un seul attribut est
défini : il s'agit de
FD_CLOEXEC, l'attribut
« close‐on‐exec ». Si le bit
FD_CLOEXEC est 0, le descripteur de fichier reste ouvert au travers
d'un
execve(2), autrement il sera fermé.
- F_GETFD (void)
- Lire les attributs du descripteur de fichier ; arg est
ignoré.
- F_SETFD (int)
- Positionner les attributs du descripteur de fichier avec la valeur
précisée par arg.
Dans un programme multithreadé, l'utilisation simultanée dans un
thread de
fcntl() avec
F_SETFD afin de définir l'attribut
« close-on-exec » (
FD_CLOEXEC), et de
fork(2) suivi de
execve(2) dans un autre thread rend le
programme vulnérable à une condition de concurrence pouvant
provoquer la fuite du descripteur de fichier vers le programme
exécuté dans le processus fils. Consultez les détails de
l'attribut
O_CLOEXEC dans
open(2) qui décrivent une
solution à ce problème.
Attribut d'état du fichier¶
Un descripteur de fichier dispose de certains attributs, initialisés par
open(2) et éventuellement modifiés par
fcntl().
Les attributs sont partagés entre les copies (obtenues avec
dup(2),
fcntl(F_DUPFD),
fork(2), etc.) du même
descripteur de fichier.
Les attributs et leurs sémantiques sont décrits dans la page
open(2).
- F_GETFL (void)
- Obtenir le mode d'accès et les attributs d'état du
fichier ; arg est ignoré.
- F_SETFL (int)
- Positionner les nouveaux attributs pour le descripteur de fichier à
la valeur indiquée par arg. Les bits de mode d'accès
( O_RDONLY, O_WRONLY, O_RDWR) et les attributs de
création ( O_CREAT, O_EXCL, O_NOCTTY,
O_TRUNC) de arg sont ignorés. Sous Linux, cette
commande ne peut changer que O_APPEND, O_ASYNC,
O_DIRECT, O_NOATIME et O_NONBLOCK. Modifier les
attributs O_DSYNC et O_SYNC est impossible, consultez
BOGUES ci-dessous.
Verrouillages coopératifs¶
F_SETLK,
F_SETLKW et
F_GETLK servent à gérer
les verrouillages d'enregistrements (de segments ou de régions de
fichiers). Le troisième argument,
lock, est un pointeur sur une
structure qui a au moins les champs suivants (dans un ordre non
indiqué).
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 d'octets à verrouiller. Des octets après
la fin du fichier peuvent être verrouillé, mais pas des octets
avant le début du fichier.
l_start est la position de début du verrou, et est
interprété de façon relative : au début du
fichier (si
l_whence vaut
SEEK_SET) ; à la
position actuelle dans le fichier (si
l_whence vaut
SEEK_CUR) ; à la fin du fichier (si
l_whence vaut
SEEK_END). Dans les deux derniers cas,
l_start peut être
un nombre négatif, à partir du moment où la position
fournie ne pointe pas avant le début du fichier.
l_len indique le nombre d'octets à verrouiller. Si
l_len
est positif, alors l'intervalle à verrouiller couvre les octets
à partir de
l_start jusqu'à
l_start+
l_len-1
(inclus). Indiquer 0 dans
l_len a une signification
particulière : cela verrouille tous les octets à partir
de la position indiquée par
l_whence et
l_start
jusqu'à la fin du fichier, quelle que soit la taille que prendra la
fichier.
POSIX.1-2001 permet (mais n'impose pas) à une implémentation de
prendre en charge des valeurs de
l_len négatives ; si
l_len est négatif, l'intervalle décrivant le verrou
lock 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.
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.
- F_SETLK (struct flock *)
- Acquérir (si l_type vaut F_RDLCK ou F_WRLCK)
ou libérer (si l_type vaut F_UNLCK) le verrou sur les
octets indiqués par les champs l_whence, l_start, et
l_len de lock. Si un conflit avec un verrou tenu par un
autre processus existe, cet appel renvoie -1 et positionne errno
aux valeurs EACCES ou EAGAIN.
- F_SETLKW (struct flock *)
- Comme F_SETLK, mais attend la libération du verrou au lieu
de retourner une erreur. Si un signal à intercepter est reçu
pendant l'attente, l'appel est interrompu et renverra immédiatement
(après retour du gestionnaire de signaux) la valeur -1.
errno sera remplie avec la valeur EINTR ; consultez
signal(7).
- F_GETLK (struct flock *)
- En entrée dans cette routine, lock décrit un verrou
que nous aimerions placer sur le fichier. Si le verrouillage est possible,
fcntl() ne le fait pas, mais renvoie F_UNLCK dans le champ
l_type de lock et laisse les autres champs de la structure
inchangés. Si un ou plusieurs verrouillages incompatibles
empêchaient l'action, alors fcntl() renvoie des informations
sur l'un de ces verrous dans les champs l_type, l_whence,
l_start, et l_len de lock et remplit l_pid
avec le PID du processus tenant le verrou. Notez que l'information
renvoyée par F_GETLK peut être devenue
obsolète au moment où l'appelant l'examine.
Pour pouvoir placer un verrou en lecture,
fd doit être ouvert au
moins en lecture. Pour placer un verrou en écriture,
fd doit
être ouvert en écriture. Pour placer les deux types de verrous,
il faut une ouverture en lecture/écriture.
Outre la suppression par un
F_UNLCK explicite, les verrous sont
automatiquement libérés lorsque le processus se termine, ou s'il
ferme
l'un des descripteurs se référant au fichier sur
lequel le verrou est placé. C'est dangereux : cela signifie
qu'un processus peut perdre un verrou sur un fichier comme
/etc/passwd
ou
/etc/mtab si, pour une raison quelconque, une fonction de
bibliothèque décide de l'ouvrir puis de le refermer.
Les verrouillages d'enregistrements ne sont pas hérités par les
enfants lors d'un
fork(2), mais sont conservés au travers d'un
execve(2).
À cause des tampons gérés par la bibliothèque
stdio(3), l'utilisation des verrous d'enregistrements avec les routines
de celle‐ci est déconseillé. Utilisez plutôt
read(2) et
write(2).
Verrouillage obligatoire¶
(Non POSIX) Les verrous d'enregistrements décrits ci‐dessus
peuvent être coopératifs ou impératifs, et sont
coopératifs par défaut.
Les verrouillages coopératifs ne sont pas imposés, donc ils ne
fonctionnent qu'entre processus qui les utilisent.
Les verrous impératifs sont appliqués à tous les processus.
Si un processus tente d'effectuer un accès incompatible (par exemple
read(2) ou
write(2)) sur une zone d'un fichier qui a un verrou
impératif, le résultat dépend de l'attribut
O_NONBLOCK du descripteur de fichier. S'il n'est pas activé,
l'appel système est bloqué jusqu'à ce que le verrou soit
enlevé ou converti en un mode compatible avec l'accès
demandé. Si l'attribut
O_NONBLOCK est activé, l'appel
système échoue avec l'erreur
EAGAIN.
Pour utiliser des verrous impératifs, ce type de verrouillage doit
être activé sur le système de fichiers contenant le
fichier à verrouiller (en utilisant l'option « -o
mand » de
mount(8)), ou l'attribut
MS_MANDLOCK de
mount(2). Le verrouillage impératif est activé pour un
fichier en désactivant la permission d'exécution du groupe et en
activant le bit de permission Set-GID (consultez
chmod(1) et
chmod(2)).
L'implémentation Linux des verrouillages obligatoires n'est pas fiable.
Consultez la section BOGUES ci-dessous.
Gestion des signaux¶
F_GETOWN,
F_SETOWN,
F_GETOWN_EX,
F_SETOWN_EX,
F_GETSIG et
F_SETSIG servent à gérer les signaux
de disponibilité d'entrée-sortie :
- F_GETOWN (void)
- Renvoyer (comme résultat de la fonction) le PID ou l'ID du groupe
de processus qui reçoit les signaux SIGIO et SIGURG
pour les événements concernant le descripteur de fichier
fd. Les groupes de processus sont renvoyés sous forme de
valeurs négatives (consultez la section BOGUES ci‐dessous).
arg est ignoré.
- F_SETOWN (int)
- Définir le PID ou l'identifiant du groupe de processus qui
recevront les signaux SIGIO et SIGURG pour les
événements concernant le descripteur fd, à
l'identifiant fourni par arg. Les groupes de processus sont
formulés en tant que valeurs négatives. En
général, le processus appelant indique son propre PID comme
argument ( arg est donc getpid(2)).
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 recevoir un autre signal que SIGIO. Si la
vérification de permissions échoue, le signal est
ignoré silencieusement.
L'envoi d'un signal au processus (ou groupe de processus) indiqué par
F_SETOWN est conditionné par les mêmes
vérifications de permissions que l'envoi d'un signal par
kill(2), où le processus envoyant le signal est celui qui
utilise F_SETOWN (consultez la section BOGUES ci‐dessous).
Si cette vérification échoue, le signal est ignoré.
Si le descripteur fd est 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 ».)
Le paragraphe ci-dessous était valide pour les noyaux 2.6.x, jusqu'au
2.6.11 inclus :
- Si une valeur non nulle est passée à F_SETSIG dans un
processus multithreadé utilisant une bibliothèque de threads
gérant les groupes de threads (par exemple NPTL), une valeur
positive passée à F_SETOWN a une signification
différente : au lieu d'être un PID identifiant tout
un processus, il s'agit d'un identifiant de thread, référant
à un thread spécifique dans un processus. Par
conséquent, il peut être nécessaire de passer
à F_SETOWN la valeur renvoyée par gettid(2)
plutôt que celle renvoyée par getpid(2) pour obtenir
les résultats souhaités si F_SETSIG est
utilisé. (Dans les implémentations actuelles des threads
sous Linux, l'identifiant de thread (TID) du thread principal est son
identifiant de processus. Cela signifie qu'un processus avec un seul
thread peut utiliser indifféremment gettid(2) ou
getpid(2).) Veuillez toutefois noter que les remarques de ce
paragraphe ne s'appliquent pas au signal SIGURG
généré lorsque des données hors‐bande
sont disponibles sur une socket : ce signal est toujours
envoyé soit à un processus, soit à un groupe de
processus, selon la valeur donnée à F_SETOWN.
- Le comportement ci-dessus a été supprimé par accident
dans Linux 2.6.12, et ne sera pas remis. À partir de Linux 2.6.32,
utilisez F_SETOWN_EX pour envoyer les signaux SIGIO et
SIGURG à un thread en particulier.
- F_GETOWN_EX (struct f_owner_ex *) (depuis Linux 2.6.32)
- Renvoyer les paramètres du propriétaire du descripteur de
fichier actuel, tels que définis par une utilisation
antérieure de F_SETOWN_EX. L'information est renvoyée
dans la structure pointée par arg, qui a la forme
suivante :
struct f_owner_ex {
int type;
pid_t pid;
};
Le champ type aura l'une des valeurs F_OWNER_TID,
F_OWNER_PID ou F_OWNER_PGRP. Le champ pid est un
entier positif représentant un identifiant de thread, de processus
ou de groupe de processus. Consultez F_SETOWN_EX pour plus de
détails.
- F_SETOWN_EX (struct f_owner_ex *) (depuis Linux 2.6.32)
- Cette opération effectue une tâche similaire à
F_SETOWN. Elle autorise l'appelant à diriger les signaux de
disponibilité d'entrées-sorties vers un thread, un processus
ou un groupe de processus spécifiques. L'appellant indique le
destinataire des signaux avec arg, qui est un pointeur vers une
structure f_owner_ex. Le champ type possède l'une des
valeurs suivantes, qui définit comment pid est
interprété :
- F_OWNER_TID
- Envoyer le signal au thread dont l'identifiant (la valeur renvoyée
par un appel à clone(2) ou gettid(2)) est
indiqué par pid.
- F_OWNER_PID
- Envoyer le signal au processus dont l'identifiant est indiqué par
pid.
- F_OWNER_PGRP
- Envoyer le signal au groupe de processus dont l'identifiant est
indiqué par pid. Notez que, à la différence de
F_SETOWN, un identifiant de groupe est indiqué ici avec une
valeur positive.
- F_GETSIG (void)
- Renvoyer (comme résultat de la fonction) le numéro du signal
émis lorsque l'entrée ou la sortie deviennent possibles. Une
valeur nulle signifie l'émission de SIGIO. Toute autre
valeur (y compris SIGIO) précise le signal émis, et
des informations supplémentaires seront disponibles pour le
gestionnaire s'il est installé avec SA_SIGINFO. arg
est ignoré.
- F_SETSIG (int)
- Définir le signal à émettre lorsque l'entrée
ou la sortie deviennent possibles à la valeur fournie par
arg. Une valeur nulle signifie l'émission de SIGIO.
Toute autre valeur (y compris SIGIO) précise le signal
à émettre, et des informations supplémentaires seront
disponibles pour le gestionnaire s'il est installé avec
SA_SIGINFO.
En utilisant F_SETSIG avec une valeur non nulle, et en configurant
SA_SIGINFO pour le gestionnaire (consultez 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 (la mémorisation dépend de la
mémoire disponible). Des informations supplémentaires sont
disponibles, comme ci‐dessus, si SA_SIGINFO est
configuré pour le gestionnaire.
Noter que Linux impose une limite sur le nombre de signaux temps réel
qui peuvent être mis en attente pour un processus (consultez
getrlimit(2) et signal(7)), et si cette limite est atteinte,
le noyau change de comportement et envoie SIGIO, et ce signal est
délivré au processus entier plutôt qu'au thread
spécifique.
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 est spécifique à BSD et Linux. La
seule utilisation de
F_GETOWN et
F_SETOWN
spécifiée dans POSIX.1 est en conjonction avec
l’utilisation du signal
SIGURG sur les sockets (POSIX ne
spécifie pas le signal
SIGIO).
F_GETOWN_EX,
F_SETOWN_EX,
F_GETSIG et
F_SETSIG sont spécifiques
à Linux. POSIX dispose 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 bibliothèque GNU C
(Glibc).
Baux¶
F_SETLEASE et
F_GETLEASE (depuis Linux 2.4) servent respectivement
à établir un nouveau bail et à consulter le bail actuel
sur le descripteur de fichier indiqué par
fd. (NdT : je
traduis « lease » par
« bail », faute de terme plus technique.) Le bail
sur un fichier fournit un mécanisme par lequel un processus
détenteur du bail est averti (par délivrance d'un signal)
lorsqu'un autre processus (le « casseur de bail »)
essaye d'appeler
open(2) ou
truncate(2) sur le fichier
pointé par ce descripteur de fichier
- F_SETLEASE (int)
- Définit ou supprime un bail de fichier en fonction de la valeur
fournie dans l'entier arg :
- F_RDLCK
- Prendre un bail en lecture. Le processus appelant sera prévenu
lorsqu'un autre processus ouvrira le fichier en écriture ou le
tronquera. Un bail en lecture ne peut être placé que sur un
descripteur de fichier ouvert en lecture seule.
- F_WRLCK
- Prendre un bail en écriture. Le processus appelant sera
prévenu lorsqu'un autre processus ouvrira le fichier (en lecture ou
écriture) ou le tronquera. Un bail en écriture ne peut
être pris sur le fichier que s'il n'y a aucun autre descripteur de
fichier ouvert pour le fichier.
- F_UNLCK
- Supprimer le bail sur un fichier.
Les baux sont associés à une description de fichier ouvert
(consultez
open(2)). Cela signifie que les descripteurs de fichier
dupliqués (créé par, par exemple,
fork(2) ou
dup(2)) font référence au même bail, et que ce
bail peut être modifié ou relâché par n'importe
lequel de ces descripteurs. De plus, le bail est relâché soit
par une opération
F_UNLCK explicite sur n'importe lequel de ces
descripteurs dupliqués, soit lorsque tous ces descripteurs ont
été fermés.
Les baux ne peuvent être pris que sur des fichiers normaux. Un processus
non privilégié ne peut prendre un bail que sur un fichier dont
l'UID (le propriétaire) correspond au FS-UID du processus. Un processus
possédant la capacité
CAP_LEASE peut prendre un bail sur
n'importe quel fichier.
- F_GETLEASE (void)
- Indique le type de bail possédé sur le descripteur de
fichier fd en renvoyant F_RDLCK, F_WRLCK, ou
F_UNLCK, signifiant respectivement que le processus appelant a un
bail en lecture, écriture, ou pas de bail sur le fichier.
arg est ignoré.
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 (par exemple 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 possède un bail en
écriture sur le fichier et que le casseur de bail ouvre le fichier en
lecture, il est suffisant 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 qu'un cassage de bail a été commencé,
F_GETLEASE renvoie le type de bail cible (
F_RDLCK ou
F_UNLCK, en fonction de ce qui serait compatible avec le casseur de
bail) jusqu'à ce que le détenteur du bail ne le déclasse
ou le supprime volontairement, ou que le noyau force à le faire
après expiration du délai de cassage de bail.
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 l'appel à
open(2) ou
truncate(2) du casseur de bail est
interrompu par un gestionnaire de signal, l'appel système échoue
avec l'erreur
EINTR, mais les autres étapes décrites
ci‐dessous se déroulent normalement. Si le casseur de bail est
tué par un signal pendant que son appel système
open(2)
ou
truncate(2) bloque, tout se déroule comme décrit
ci‐dessus. De même, si le casseur de bail utilise l'option
O_NONBLOCK de
open(2), l'appel retourne immédiatement
avec l'erreur
EWOULDBLOCK, mais les autres étapes se
déroulent comme décrit ci‐dessus.
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
baux sur plusieurs fichiers.)
Notification de modification de fichier et de répertoire (dnotify)¶
- F_NOTIFY (int)
- (Depuis Linux 2.4) Fournit un avertissement lorsque le répertoire
correspondant à fd ou l'un des fichiers qu'il contient est
modifié. Les événements à notifier sont
précisés dans arg, sous forme de masque regroupant
par un OU binaire zéro, une ou plusieurs des constantes
suivantes :
- DN_ACCESS
- Accès à un fichier (read, pread, readv)
- DN_MODIFY
- Modification d'un fichier (write, pwrite, truncate, ftruncate).
- DN_CREATE
- Création d'un fichier (open, creat, mknod, mkdir, link, symlink,
rename).
- DN_DELETE
- Suppression d'un fichier (unlink, renommage dans un autre
répertoire, rmdir).
- DN_RENAME
- Un fichier a été renommé dans le même
répertoire (nerame).
- DN_ATTRIB
- Les attributs d'un fichier ont été modifiés (chown,
chmod, utime[s]).
- (Afin d'obtenir ces définitions, la macro _GNU_SOURCE doit
être définie avant d'inclure tout fichier
d'en‐tête).
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 utiliser
l'interface inotify (disponible depuis Linux 2.6.13), qui fournit
une bien meilleure interface pour obtenir des notifications
d'événements sur le système de fichiers. Consultez
inotify(7).
Changer la capacité d'un tube¶
- F_SETPIPE_SZ (int ; depuis Linux 2.6.35)
- Change la capacité du tube référencé par
fd pour contenir au moins arg octets. Un processus non
privilégié peut ajuster la capacité d'un tube
à toute valeur comprise entre la taille de page du système
et la limite définie dans /proc/sys/fs/pipe-max-size
(consultez proc(5)). Les tentatives pour définir la
capacité du tube en dessous de la taille de page sont
silencieusement arrondies à la taille de page. Les tentatives d'un
processus non privilégié pour définir la
capacité du tube au dessus de /proc/sys/fs/pipe-max-size
renvoie l'erreur EPERM ; un processus
privilégié ( CAP_SYS_RESOURCE) peut passer outre
cette limite. Quand il alloue le tampon pour le tube, le noyau peut
utiliser une capacité supérieure à arg, si
cela est plus pratique pour l'implémentation. L'opération
F_GETPIPE_SZ renvoie la taille réellement utilisée.
Les tentatives pour définir la capacité du tube en dessous
de la capacité du tampon actuellement utilisé pour
sauvegarder les données produit l'erreur EBUSY.
- F_GETPIPE_SZ (void ; depuis Linux 2.6.35)
- Renvoie (comme résultat de la fonction) la capacité du tube
référencé par fd.
VALEUR RENVOYÉE¶
La valeur renvoyée par
fcntl() varie suivant le type
d'opération :
- F_DUPFD
- Le nouveau descripteur.
- F_GETFD
- Valeur des attributs du descripteur de fichier.
- F_GETFL
- Valeur des attributs d'état du fichier.
- F_GETLEASE
- Le type bail tenu sur le descripteur de fichier.
- F_GETOWN
- Le propriétaire du descripteur de fichier.
- F_GETSIG
- La valeur du signal envoyé lorsque la lecture ou l'écriture
deviennent possibles, ou zéro pour le comportement SIGIO
traditionnel.
- F_GETPIPE_SZ
- La capacité du tube.
- Toutes les autres commandes :
- Zéro.
En cas d'erreur, la valeur de retour est -1, et
errno contient le code
d'erreur.
ERREURS¶
- EACCES ou EAGAIN
- L'opération est interdire en raison de verrous tenus par d'autres
processus.
- EAGAIN
- L'opération est impossible à cause d'une projection en
mémoire effectuée par un autre processus.
- EBADF
- fd n'est pas un descripteur de fichier ouvert, ou la commande
était F_SETLK ou F_SETLKW et le mode d'ouverture du
descripteur de fichier ne correspond pas au type de verrou
demandé.
- EDEADLK
- Le verrouillage F_SETLKW conduirait à un blocage.
- EFAULT
- lock se trouve en dehors de l'espace d'adressage.
- EINTR
- Pour F_SETLKW, la commande a été interrompue par un
signal ; consultez signal(7). Pour F_GETLK et
F_SETLK, la commande a été interrompue par un signal
avant la vérification ou l'acquisition du verrou. Se produit
surtout lors d'un verrouillage distant (par exemple à travers NFS),
mais peut également arriver localement.
- EINVAL
- Pour F_DUPFD, arg est soit négatif, soit trop grand.
Pour F_SETSIG, arg n'est pas un numéro de signal
correct.
- EMFILE
- Pour F_DUPFD, le processus a déjà ouvert le nombre
maximal de descripteurs de fichier.
- ENOLCK
- Trop de verrous sont ouverts, ou la table des verrous est pleine, ou le
verrouillage distant (par exemple par NFS) a échoué.
- EPERM
- Essai d'effacement de l'attribut O_APPEND sur un fichier, mais il
est considéré comme en-ajout-seulement.
SVr4, BSD 4.3, POSIX.1-2001. Seules les opérations
F_DUPFD,
F_GETFD,
F_SETFD,
F_GETFL,
F_SETFL,
F_GETLK,
F_SETLK et
F_SETLKW sont
spécifiées dans POSIX.1-2001.
F_GETOWN et
F_SETOWN sont spécifiées dans
POSIX.1-2001. Pour activer ces définitions, vous devez définir
_BSD_SOURCE, ou
_XOPEN_SOURCE avec une valeur supérieure
ou égale à 500, ou
_POSIX_C_SOURCE avec une valeur
supérieure ou égale à 200809L.
F_GETOWN est spécifiée dans POSIX.1-2008. Pour activer
cette définition, vous devez
_POSIX_C_SOURCE avec une valeur
supérieure ou égale à 200809L, ou
_XOPEN_SOURCE
avec une valeur supérieure ou égale à 700.
F_GETOWN_EX,
F_SETOWN_EX,
F_SETPIPE_SZ,
F_GETPIPE_SZ,
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¶
L'appel système
fcntl() original de Linux n'a pas
été conçu pour gérer les positions (dans la
structure
flock) dans des fichiers de très grosse taille. En
conséquence, Linux 2.4 a ajouté l'appel système
fcntl64(). Ce nouvel appel système utilise une structure
différente de verrouillage de fichier,
flock64, ainsi que les
commandes correspondantes
F_GETLK64,
F_SETLK64 et
F_SETLKW64. Cependant, ces détails peuvent être
ignorés par les applications qui utilisent la glibc, car sa fonction
fcntl() encapsule de manière transparente l'appel système
le plus récent disponible.
Les erreurs renvoyées par
dup2(2) ne sont pas les mêmes que
celles renvoyées par
F_DUPFD.
Depuis le noyau 2.0, il n'y a pas d'interaction entre les verrous placés
par
flock(2) et ceux de
fcntl().
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¶
F_SETFL¶
Il n'est pas possible d'utiliser
F_SETFL pour modifier l'état des
attributs
O_DSYNC et
O_SYNC. Une tentative de modification de
ces attributs sera simplement ignorée.
F_GETOWN¶
En raison d'une limitation des conventions d'appels système sur certaines
architectures (en particulier i386), si
F_GETOWN renvoie un identifiant
de groupe de processus compris entre -1 et -4095, la valeur de retour est
interprétée par glibc comme une erreur ; la valeur de
retour de
fcntl() sera -1 et
errno contiendra l'identifiant du
groupe de processus (positif). Les opérations spécifiques
à Linux
F_SETOWN_EX et
F_GETOWN_EX évitent ce
problème. Depuis la glibc 2.11, glibc rend le problème avec
F_GETOWN invisible en implémentant
F_GETOWN par-dessus
F_GETOWN_EX.
F_SETOWN¶
Sous Linux 2.4 et précédents, lorsqu'un processus non
privilégié utilise
F_SETOWN pour indiquer le
propriétaire d'une socket, avec un identifiant de (groupe de) processus
autre que celui de l'appelant, un bogue peut survenir. Dans ce cas,
fcntl() peut renvoyer -1, avec
errno positionné à
EPERM, même si l'appelant a le droit d'envoyer un signal
à ce (groupe de) processus. En dépit de cette erreur, le
propriétaire du descripteur de fichier est positionné, et les
signaux seront envoyés au propriétaire.
Verrouillage obligatoire¶
L'implémentation du verrouillage obligatoire dans toutes les versions
connues de Linux est sujet à des conditions de concurrence qui la rende
non fiable : un appel à
write(2) qui chevauche un verrou
peut modifier les données après que le verrouillage obligatoire
a é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 a é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¶
dup2(2),
flock(2),
open(2),
socket(2),
lockf(3),
capabilities(7),
feature_test_macros(7)
locks.txt,
mandatory-locking.txt et
dnotify.txt dans le
répertoire
Documentation/filesystems/ des sources du noyau
Linux. (Sur d'anciens noyaux, ces fichiers se trouvent dans le
répertoire
Documentation/ et
mandatory-locking.txt est
appelé
mandatory.txt.)
COLOPHON¶
Cette page fait partie de la publication 3.65 du projet
man-pages Linux.
Une description du projet et des instructions pour signaler des anomalies
peuvent être trouvées à l'adresse
http://www.kernel.org/doc/man-pages/.
TRADUCTION¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a
<
http://po4a.alioth.debian.org/> par l'équipe de traduction
francophone au sein du projet perkamon
<
http://perkamon.alioth.debian.org/>.
Christophe Blaess <
http://www.blaess.fr/christophe/> (1996-2003), Alain
Portal <
http://manpagesfr.free.fr/> (2003-2006). Julien Cristau et
l'équipe francophone de traduction de Debian (2006-2009).
Veuillez signaler toute erreur de traduction en écrivant à
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet
manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce
document en utilisant la commande «
man -L C
<section>
<page_de_man> ».