flock - Placer ou enlever un verrou partagé sur un fichier ouvert
Bibliothèque C standard (
libc,
-lc)
#include <sys/file.h>
int flock(int fd, int operation);
Placer ou enlever un verrou partagé sur un fichier ouvert dont le
descripteur est
fd. Le paramètre
operation est l'un des
suivants :
- LOCK_SH
- Verrouillage partagé. Plusieurs processus peuvent
disposer d'un verrouillage partagé simultanément sur un
même fichier à un moment donné.
- LOCK_EX
- Verrouillage exclusif. Un seul processus dispose d'un
verrouillage exclusif sur un fichier à un moment donné.
- LOCK_UN
- Déverrouillage d'un verrou tenu par le
processus.
Un appel
flock() peut bloquer si un verrou incompatible est tenu par un
autre processus. Pour qu’une requête soit non‐bloquante,
il faut inclure
LOCK_NB (par un
OU binaire
« | » ) avec n’importe quelle
opération ci-dessus.
Un même fichier ne peut pas avoir simultanément des verrous
partagés et exclusifs.
Les verrous créés avec
flock() sont associés
à un descripteur de fichier ouvert (consultez
open(2)). Ainsi,
les descripteurs de fichier dupliqués (par exemple avec
fork(2)
ou
dup(2)) réfèrent au même verrou, et
celui‐ci peut être relâché ou modifié en
utilisant un des ces descripteurs de fichier. De plus, un verrou est
relâché par une opération explicite
LOCK_UN sur
l'un quelconque de ces descripteurs de fichier dupliqués ou lorsqu'ils
ont tous été fermés.
Si un processus utilise
open(2) (ou équivalent) pour avoir plus
d'un descripteur de fichier pour un même fichier, ces descripteurs de
fichier sont traités indépendamment par
flock(). Une
tentative de verrouiller le fichier avec l'un de ces descripteurs peut
être refusée si le processus appelant a déjà
placé un verrou en utilisant un autre descripteur de fichier.
Un processus ne peut avoir qu'un seul type de verrou (partagé ou
exclusif) sur un fichier. En conséquence un appel
flock() sur un
fichier déjà verrouillé modifiera le type de
verrouillage.
Les verrous créés par
flock() sont conservés
à la fin d'un
execve(2).
Un verrou partagé ou exclusif peut être placé sur un
fichier quel que soit le mode d'ouverture du fichier.
En cas de succès, zéro est renvoyé. En cas d'erreur,
-1 est renvoyé et
errno est définie pour
préciser l'erreur.
- EBADF
-
fd n'est pas un descripteur de fichier ouvert.
- EINTR
- Durant l'attente pour acquérir le verrou, l'appel a
été interrompu par un signal capturé par un
gestionnaire ; consultez signal(7).
- EINVAL
-
operation n’est pas acceptable.
- ENOLCK
- Le noyau n'a pas assez de mémoire pour les
allocations de verrou.
- EWOULDBLOCK
- Le fichier est verrouillé et l'attribut
LOCK_NB a été précisé.
4.4BSD (l'appel système
flock() est apparu dans 4.2BSD). Une
version de
flock(), parfois implémentée à partir
de
fcntl(2), est apparue sur la plupart des systèmes UNIX.
Depuis Linux 2.0,
flock() est implémenté comme un
appel système à part entière plutôt que
d'être émulé par une routine de la bibliothèque
GNU C invoquant
fcntl(2). Avec cette implémentation, il
n'y a pas d'interaction entre les verrous placés par
flock() et
fcntl(2), et
flock() ne détecte pas les cas
d’interblocage (deadlock) (remarquez, cependant, que sur certains BSD
modernes, les verrouillages
flock() et
fcntl(2)
interagissent entre eux).
flock() place uniquement des verrous partagés : suivant les
permissions du fichier un processus peut ignorer l'utilisation de
flock() et faire des entrées-sorties sur le fichier.
Les sémantiques des verrous placés par
flock() et
fcntl(2) sont différentes en ce qui concerne
fork(2) et
dup(2). Sur les systèmes qui implémentent
flock()
en utilisant
fcntl(2), la sémantique de
flock() sera
différente de celle décrite ici.
La conversion d'un verrou (de partagé à exclusif et vice versa)
n'est pas toujours atomique : tout d'abord le verrou existant est
supprimé, puis un nouveau verrou est établi. Entre ces deux
étapes, un verrou demandé par un autre processus peut
être accordé, ce qui peut causer soit un blocage de la
conversion, soit son échec, si
LOCK_NB était
indiqué. (Cela est le comportement BSD d'origine, et est partagé
par de nombreuses implémentations.)
Jusqu’à Linux 2.6.11,
flock() ne verrouille pas les
fichiers à travers NFS (à savoir que le but des verrous a
été limité au système local). Utilisez
plutôt
fcntl(2) pour verrouiller une plage d'octets, qui
fonctionne avec NFS si la version de Linux est suffisamment récente et
si le serveur accepte les verrouillages.
Depuis Linux 2.6.12, les clients NFS prennent en charge les verrouillages
flock() en les émulant sous la forme de verrous de plages
d'octets
fcntl(2) sur tout le fichier. Cela signifie que les
verrouillages
fcntl(2) et
flock()
interagissent entre eux
avec NFS. Cela veut dire que pour poser un verrouillage exclusif, le fichier
doit être ouvert en écriture.
Depuis Linux 2.6.37, le noyau gère un mode de compatibilité qui
permet aux verrouillages
flock() (et aux verrous d'une plage d'octets
fcntl(2)) d'être traités en local ; voir le point
sur l'option
local_lock dans
nfs(5).
Jusqu'à Linux 5.4,
flock() n'est pas propagé par
SMB. Un fichier ayant de tels verrous n'apparaitra pas verrouillé pour
les clients distants.
Depuis Linux 5.5,
flock(), les verrous sont émulés avec
ceux par plage d’octets SMB sur tout le fichier. Comme pour NFS, cela
veut dire que les verrous
fcntl(2) et
flock() interagissent
entre eux. Un autre effet de bord important est que les verrous ne sont plus
partagé : n'importe quelle E/S sur un fichier verrouillé
échouera toujours avec l'erreur
EACCES si elle vient d'un autre
descripteur de fichier. Cette différence vient de la conception
même des verrous dans le protocole SMB, qui fournit une
sémantique de verrouillage exclusif.
La sémantique des verrous distants et exclusifs peut varier selon le
protocole SMB, les options de montage et le type de serveur. Voir
mount.cifs(8) pour des informations supplémentaires.
flock(1),
close(2),
dup(2),
execve(2),
fcntl(2),
fork(2),
open(2),
lockf(3),
lslocks(8)
Documentation/filesystems/locks.txt dans les sources du noyau Linux (
Documentation/locks.txt pour les anciens noyaux)
La traduction française de cette page de manuel a été
créée par Christophe Blaess
<
https://www.blaess.fr/christophe/>, Stéphan Rafin
<
[email protected]>, Thierry Vignaud
<
[email protected]>, François Micaux, Alain Portal
<
[email protected]>, Jean-Philippe Guérard
<
[email protected]>, Jean-Luc Coulon (f5ibh)
<
[email protected]>, Julien Cristau
<
[email protected]>, Thomas Huriaux <
[email protected]>,
Nicolas François <
[email protected]>, Florentin
Duneau <
[email protected]>, Simon Paillard
<
[email protected]>, Denis Barbier
<
[email protected]>, David Prévot <
[email protected]> et
Jean-Philippe MENGUAL <
[email protected]>
Cette traduction est une documentation libre ; veuillez vous reporter
à la
GNU
General Public License version 3 concernant les conditions de copie
et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel,
veuillez envoyer un message à
[email protected]