FCNTL(2)

NOM
fcntl - Manipuler un descripteur de fichier

SYNOPSIS
#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
fcntl() permet de se livrer à l'une des opérations décrites plus loin sur le descripteur de fichier fd. L'opération est déterminée par la valeur de l'argument cmd.

  Dupliquer un descripteur de fichier

F_DUPFD
    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 (depuis Linux 2.6.24)
    Comme pour un 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 restera ouvert même au travers d'un exec(2), autrement il sera fermé.

F_GETFD
    Lire les attributs du descripteur de fichier.

F_SETFD
    Positionner les attributs du descripteur de fichier avec la valeur spécifiée par arg.

  Attribut d'état du fichier
Chaque description de fichier ouvert dispose de certains attributs d'état, initialisés par open(2) et éventuellement modifiés par fcntl(). Les descripteurs de fichier dupliqués (obtenus avec dup(2), fcntl(F_DUPFD), fork(2), etc.) font référence à la même description de fichier et partagent ainsi les mêmes attributs d'état de fichier. Les attributs d'état de fichier et leurs sémantiques sont décrits dans la page open(2).

F_GETFL
    Lire les attributs d'état du fichier.

F_SETFL
    Positionner les nouveaux attributs d'état pour le fichier à la valeur indiquée par arg. Les modes d'accès au fichier (O_RDONLY, O_WRONLY, O_RDWR) et les attributs de création du fichier (c'est-à-dire O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) dans arg sont ignorés. Sous Linux, cette commande ne peut changer que les attributs 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) */
    ...
};
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 nombre 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, quelle que 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.

F_SETLK
    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
    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 renseignée avec la valeur EINTR ; voir signal(7).

F_GETLK
    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. 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 préservé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, ils ne fonctionnent donc qu'entre les processus qui les utilisent. Les verrous 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 verrou 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'appel système bloquera jusqu'à ce que le verrou soit enlevé ou converti en 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é 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 BOGUES plus loin.

  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
    Obtenir 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 PID sont renvoyés sous forme de valeurs positives ; les groupes de processus sont renvoyés sous forme de valeurs négatives (mais voir la section BOGUES plus bas).

F_SETOWN
    Définir le PID ou l'ID du groupe de processus qui recevront les signaux SIGIO et SIGURG pour les événements concernant le descripteur fd. Un PID est formulé en tant que valeur positive ; les ID de groupes de processus sont formulés en tant que valeurs négatives. Plus communément, le processus appelant se spécifie lui-même comme le propriétaire (c'est-à-dire que arg vaut 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 obtenir la délivrance d'un signal autre que SIGIO. Si cette vérification de permissions é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 cette vérification échoue, le signal est silencieusement abandonné. 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 multithreadé en cours d'exécution avec une bibliothèque de threads qui gérant les groupes de threads (par exemple NPTL), alors une valeur positive fournie a F_SETOWN à une signification différente : plutôt que d'être un PID identifiant 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 la valeur renvoyée par gettid(2) plutôt que celle renvoyée par getpid(2) pour obtenir des résultats sensés lorsque F_SETSIG est utilisé. (Dans les implémentations actuelles des threads Linux, l'dentifiant du thread (TID) principal est identique à son PID. Cela signifie qu'un programme simple thread peut indifféremment utiliser gettid(2) ou getpid(2) dans ce scenario.) Veuillez toutefois noter que les instructions dans 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 sur le nombre de signaux temps réel pouvant être mis en file d'attente dans un processus (voir getrlimit(2) et signal(7)). Si cette limite est atteinte, le noyau recommence à envoyer SIGIO et ce signal est délivré au processus entier et non à un thread particulier.

F_GETSIG
    Renvoyer 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.

F_SETSIG
    Indiquer le signal à émettre 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 à émettre, et des informations supplémentaires seront disponibles pour le gestionnaire s'il est installé avec SA_SIGINFO. 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 description de F_SETOWN pour plus de détails. En utilisant F_SETDSIG 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 glibc.

  Baux
F_SETLEASE et F_GETLEASE (depuis Linux 2.4) servent respectivement à établir un nouveau bail, et récupérer le bail actuel, sur la description de fichier ouvert indiquée par le descripteur de fichier 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 référencé par ce descripteur de fichier.

F_SETLEASE
    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 lorsque le fichier sera ouvert en écriture ou tronqué. Un bail en lecture ne peut être placé sur un descripteur de fichier que s'il est ouvert en lecture seule.

    F_WRLCK
        Prendre un bail en écriture. Le processus appelant sera prévenu lorsque le fichier sera ouvert en écriture ou tronqué. Un bail en écriture ne peut être pris sur un fichier seulement si aucun autre descripteur de fichier n'est ouvert sur ce 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 mofifié 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
    Indique que le type de bail est associé au descripteur de fichier fd en renvoyant F_RDLCK, F_WRLCK, ou F_UNLCK, pour signifier respectivement un bail en lecture, un bail en écriture, ou pas de bail. (Le troisième argument de fcntl() est omis).

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 loin. 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 loin. 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 loin. 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
    (Nouveauté 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, writev, 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 (rename)
    DN_ATTRIB
        Les attributs d'un fichier ont été modifiés (chown, chmod, utime[s])

    (Afin d'obtenir ces définitions, la macro de test de fonctionnalités _GNU_SOURCE_ doit être définie.) 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 considérer l'utilisation de l'interface inotify (disponible depuis le noyau 2.6.13), qui fournit une meilleure interface pour l'obtention de 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
    Type de la tenue de bail 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 renvoient zéro.

En cas d'échec -1 est renvoyé, auquel cas errno est renseigné en conséquence.

ERREURS

EACCES  ou  EAGAIN
    L'opération est impossible en raison de verrous tenu par d'autres processus.

EAGAIN
    L'opération est impossible à cause d'une projection en mémoire effectuée par un autre processus.

EBADF
    fs 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 à celui du 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 ; voir 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 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_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(). 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
Une limitation dans les conventions des appels système Linux sur certaines architectures (notemment i386) indiquant que si le GID (négatif) d'un processus renvoyé par F_GETOWN se trouve dans entre -1 et -4095, alors la valeur de retour est faussement interprétée par la glibc comme une erreur dans l'appel système ; ainsi, la valeur de retour de fcntl() sera -1, et errno contiendra le GID (positif) du processus. Sous Linux 2.4 et antérieurs, 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 : 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)

Voir aussi les fichiers Documentation/locks.txt, Documentation/mandatory.txt et Documentation/dnotify.txt dans les sources du noyau.

TRADUCTION

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 17 juillet 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.