NOM
fcntl - Manipuler un descripteur de fichier
SYNOPSIS
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
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 long, 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 (long)
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é.
Voir dup(2) pour plus d’informations.
F_DUPFD_CLOEXEC (long ; depuis Linux 2.6.24)
Comme pour F_DUPFD, mais positionne en plus l’attribut
« close-on-exec » pour le descripteur dupliqué. Spécifier 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, voir 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 (long)
Positionner les attributs du descripteur de fichier avec la
valeur précisée par arg.
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)
Lire les attributs d’état du fichier ; arg est ignoré.
F_SETFL (long)
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.
Verrouillages coopératifs
F_GETLK, F_SETLK et F_SETLKW 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 spécifié) :
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) */
...
};
Existent aussi en env. 32 bits : F_GETLK64, F_SETLK64 et F_SETLKW64 :
struct flock64 {
...
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 */
off64_t l_start; /* Décalage de début du verrouillage */
off64_t l_len; /* Nombre d’octets du verrouillage */
pid_t l_pid; /* PID du processus bloquant notre verrou
(F_GETLK64) */
...
};
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_SETLK64 (struct flock64 *)
Idem, sauf argument.
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 ; voir
signal(7).
F_SETLKW64 (struct flock64 *)
Idem, sauf argument.
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.
F_GETLK64 (struct flock64 *)
Idem, sauf argument.
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
lun 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 (voir chmod(1) et chmod(2)).
L’implémentation Linux des verrouillages obligatoires n’est pas fiable.
Voir la section BOGUES ci-dessous.
Gestion des signaux
F_GETOWN, F_SETOWN, 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 (voir la section BOGUES ci‐dessous). arg est ignoré.
F_SETOWN (long)
Fixer 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 fixez 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)
spécifié 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 (voir 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 ».)
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.
Notez également que Linux impose une limite au nombre de signaux
temps‐réel pouvant être mis en attente pour un processus (voir
getrlimit(2) et signal(7)), et lorsque cette limite est
atteinte, le noyau recommence à envoyer SIGIO, qui est envoyé à
tout le processus, et non à un thread en particulier.
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 (long)
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 passant une valeur non nulle à F_SETSIG, le récepteur du
signal est un thread spécifique, plutôt qu’un processus entier.
Voir la description de F_SETOWN pour plus de détails.
En utilisant F_SETSIG 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 (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.
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, F_SETOWN est spécifique BSD et
Linux. 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 (long)
Fixe 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 (voir
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 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 (long)
(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 l’inclusion de <fcntl.h>.)
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. Voir inotify(7).
VALEUR RENVOYÉE
La valeur renvoyée par fcntl() varie suivant le type d’opération :
F_DUPFD Le nouveau descripteur.
F_GETFD La valeur des attributs.
F_GETFL La valeur des attributs.
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.
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, F_SETLKW, F_SETLK64 ou F_SETLKW64 et le mode
d’ouverture du descripteur de fichier ne correspond pas au type
de verrou demandé.
EDEADLK
Le verrouillage F_SETLKW (ou F_SETLKW64) conduirait à un blocage.
EFAULT lock se trouve en dehors de l’espace d’adressage.
EINTR
Pour F_SETLKW (ou F_SETLKW64), la commande a été interrompue par
un signal ; voir signal(7). Pour F_GETLK et F_SETLK (resp.
F_GETLK64 et F_SETLK64), 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 via NFS) a
échoué.
EPERM Essai d’effacement de l’attribut O_APPEND sur un fichier, mais
il est considéré comme en-ajout-seulement.
CONFORMITÉ
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, F_SETLKW, F_GETOWN et
F_SETOWN sont spécifiées dans POSIX.1-2001.
F_DUPFD_CLOEXEC est spécifié dans POSIX.1-2008.
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
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
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).
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.
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 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
dup2(2), flock(2), open(2), socket(2), lockf(3), capabilities(7),
feature_test_macros(7)
Consultez aussi locks.txt, mandatory-locking.txt et dnotify.txt dans le
répertoire Documentation/filesystems des sources du noyau (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.23 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
Cette page de manuel a été traduite et mise à jour par Christophe
Blaess <http://www.blaess.fr/christophe/> entre 1996 et 2003, puis par
Alain Portal <aportal AT univ-montp2 DOT fr> jusqu’en 2006, et mise à
disposition sur http://manpagesfr.free.fr/.
Révisé pour ce site par l'équipe man-linux-magique.net (Octobre 2010).
Les mises à jour et corrections de la version présente dans Debian sont
directement gérées par Julien Cristau <jcristau@debian.org> et l’équipe
francophone de traduction de Debian.
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> ».