flock(2)

NUME
flock - aplică sau elimină o blocare consultativă pe un fișier deschis

BIBLIOTECA
Biblioteca C standard (libc, -lc)

SINOPSIS
#include <sys/file.h>

int flock(int fd, int op);

DESCRIERE
Aplică sau elimină o blocare consultativă pe fișierul deschis specificat de fd. Argumentul op este unul dintre următoarele:

    LOCK_SH
        Plasează o blocare partajată. Mai mult de un proces poate deține o blocare partajată pentru un anumit fișier la un moment dat.

    LOCK_EX
        Plasează o blocare exclusivă. Un singur proces poate deține o blocare exclusivă pentru un anumit fișier la un moment dat.

    LOCK_UN
        Elimină o blocare existentă deținută de acest proces.

Un apel la flock() se poate bloca dacă un alt proces deține o blocare incompatibilă. Pentru a face o cerere neblocantă, includeți LOCK_NB (printr-un SAU logic) cu oricare dintre operațiile de mai sus.

Un singur fișier nu poate avea simultan blocaje partajate și exclusive.

Blocajele create de flock() sunt asociate cu o descriere de fișier deschis (a se vedea open(2)). Aceasta înseamnă că descriptorii de fișier duplicați (creați, de exemplu, prin fork(2) sau dup(2)) se referă la același blocaj, iar acest blocaj poate fi modificat sau eliberat utilizând oricare dintre acești descriptori de fișier. În plus, blocajul este eliberat fie printr-o operație explicită LOCK_UN asupra oricăruia dintre acești descriptori de fișier duplicat, fie atunci când toți acești descriptori de fișier au fost închiși.

Dacă un proces utilizează open(2) (sau similar) pentru a obține mai mult de un descriptor de fișier pentru același fișier, acești descriptori de fișier sunt tratați independent de flock(). O încercare de blocare a fișierului folosind unul dintre acești descriptori de fișier poate fi refuzată de o blocare pe care procesul apelant a plasat-o deja printr-un alt descriptor de fișier.

Un proces poate deține un singur tip de blocare (partajată sau exclusivă) pe un fișier. Apelurile ulterioare flock() pe un fișier deja blocat vor converti un blocaj existent în noul mod de blocare.

Blocajele create de flock() sunt păstrate în timpul unui execve(2).

O blocare partajată sau exclusivă poate fi plasată pe un fișier indiferent de modul în care a fost deschis fișierul.

VALOAREA RETURNATĂ
În caz de succes, se returnează zero. În caz de eroare, se returnează -1, iar errno este configurată pentru a indica eroarea.

ERORI-IEȘIRE

EBADF
    fd nu este un descriptor de fișier deschis.

EINTR
    În timp ce aștepta să obțină un blocaj, apelul a fost întrerupt de livrarea unui semnal capturat de un gestionar; a se vedea signal(7).

EINVAL
    op nu este valid.

ENOLCK
    Nucleul a rămas fără memorie pentru alocarea înregistrărilor de blocare.

EWOULDBLOCK
    Fișierul este blocat și fanionul LOCK_NB a fost selectat.

VERSIUNI
Începând cu Linux 2.0, flock() este implementat ca un apel de sistem de sine stătător în loc să fie emulat în biblioteca GNU C ca un apel către fcntl(2). Cu această implementare, nu există nicio interacțiune între tipurile de blocare plasate de flock() și fcntl(2), iar flock() nu detectează blocajul. Rețineți, totuși, că pe unele sisteme, cum ar fi BSD-urile moderne, blocajele flock() și fcntl(2) interacționează între ele.

  Detalii privind CIFS
Până la Linux 5.4, flock() nu este propagat prin SMB. Un fișier cu astfel de blocaje nu va apărea blocat pentru clienții de la distanță.

Începând cu Linux 5.5, blocajele flock() sunt emulate cu blocări ale intervalului de octeți SMB pe întregul fișier. În mod similar cu NFS, aceasta înseamnă că blocajele fcntl(2) și flock() interacționează între ele. Un alt efect secundar important este că blocajele nu mai sunt consultative: orice IO pe un fișier blocat va eșua întotdeauna cu EACCES atunci când este efectuată de la un descriptor de fișier separat. Această diferență provine din proiectarea blocajelor în protocolul SMB, care oferă o semantică de blocare obligatorie.

Semantica blocării la distanță și obligatorii poate varia în funcție de protocolul SMB, opțiunile de montare și tipul de server. Consultați mount.cifs(8) pentru informații suplimentare.

STANDARDE
BSD.

ISTORIC
4.4BSD (apelul flock() a apărut pentru prima dată în 4.2BSD). O versiune a flock(), eventual implementată în termeni de fcntl(2), apare pe majoritatea sistemelor UNIX.

  Detalii privind NFS
Până la Linux 2.6.11, flock() nu bloca fișiere prin NFS (adică, domeniul de aplicare al blocajelor era limitat la sistemul local). În schimb, se poate utiliza blocarea intervalului de octeți fcntl(2), care funcționează pe NFS, având în vedere o versiune suficient de recentă de Linux și un server care acceptă blocarea.

Începând cu Linux 2.6.12, clienții NFS acceptă blocajele flock() prin emularea lor ca blocări de interval de octeți fcntl(2) pe întregul fișier. Aceasta înseamnă că blocajele fcntl(2) și flock() do interacționează între ele pe NFS. Aceasta înseamnă, de asemenea, că pentru a plasa o blocare exclusivă, fișierul trebuie să fie deschis pentru scriere.

Începând cu Linux 2.6.37, nucleul acceptă un mod de compatibilitate care permite ca blocajele flock() (și, de asemenea, blocajele regiunii de octeți fcntl(2)) să fie tratate ca locale; a se vedea discuția despre opțiunea local_lock din nfs(5).

NOTE
flock() plasează numai blocaje consultative; având în vedere permisiunile adecvate asupra unui fișier, un proces este liber să ignore utilizarea flock() și să efectueze I/O asupra fișierului.

Blocajele flock() și fcntl(2) au semantici diferite cu privire la procesele bifurcate și dup(2). Pe sistemele care implementează flock() folosind fcntl(2), semantica lui flock() va fi diferită de cea descrisă în această pagină de manual.

Conversia unui blocaj (partajat în exclusiv sau viceversa) nu este garantată ca fiind atomică: blocajul existent este mai întâi eliminat, iar apoi se stabilește un nou blocaj. Între acești doi pași, o cerere de blocare în așteptare din partea unui alt proces poate fi acordată, rezultatul fiind fie blocarea conversiei, fie eșecul acesteia dacă a fost specificat LOCK_NB; (acesta este comportamentul BSD original și apare în multe alte implementări.)

Eliberarea unui blocaj atunci când un descriptor de fișier este închis nu este secvențiată după toate efectele observabile ale close(2). De exemplu, dacă un proces scrie un fișier în timp ce deține un blocaj exclusiv, apoi închide acel fișier, iar un alt proces blochează plasarea unui blocaj partajat pe acel fișier pentru a aștepta până când acesta este închis, se poate observa că un execve(2) ulterior al acelui fișier eșuează cu ETXTBSY, iar umount(2) al sistemului de fișiere subiacent eșuează cu EBUSY, ca și cum fișierul ar fi încă deschis în primul proces.

CONSULTAȚI ȘI
flock(1), close(2), dup(2), execve(2), fcntl(2), fork(2), open(2), lockf(3), lslocks(8)

Documentation/filesystems/locks.rst în arborele sursă al nucleului Linux

TRADUCERE
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 (https://www.gnu.org/licenses/gpl-3.0.html) sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.