FCNTL |
Fonction de contrôle |
---|---|
C pour Unix | fcntl.h |
Syntaxe
int fcntl(int fildes, int cmd, ...); |
Paramètres
Nom | Description |
---|---|
fildes | Ce paramètre permet d'indiquer le descripteur de fichier à modifier. Il est obtenu via open, socket, pipe, ou d'autres appels système retournant un descripteur de fichier valide. |
cmd | Ce paramètre permet d'indiquer l'action à effectuer sur fildes. Il existe plusieurs commandes disponibles (voir plus bas). |
... | Selon la valeur de cmd, un paramètre supplémentaire peut être requis. Il peut s'agir d'un entier (int), d'une structure (struct flock pour le verrouillage de fichiers),... |
Retour
En cas de réussite, la valeur renvoyée dépendra de cmd comme suit :
Constante | Description |
---|---|
F_DUPFD | Un nouveau descripteur de fichier. |
F_DUPFD_CLOEXEC | Un nouveau descripteur de fichier. |
F_GETFD | Valeur des indicateurs définis dans <fcntl.h>. La valeur renvoyée ne doit pas être négative. |
F_SETFD | Valeur différente de -1. |
F_GETFL | Valeur des indicateurs d'état et des modes d'accès du fichier. La valeur renvoyée n'est pas négative. |
F_SETFL | Valeur différente de -1. |
F_GETLK | Valeur différente de -1. |
F_SETLK | Valeur différente de -1. |
F_SETLKW | Valeur différente de -1. |
F_GETOWN | Valeur du processus ou du groupe de processus propriétaire du socket ; cette valeur ne sera pas -1. |
F_SETOWN | Valeur différente de -1. |
Sinon, la valeur -1 sera renvoyée et errno sera défini pour indiquer l'erreur.
Description
Cette fonction permet d'effectuer des opérations de contrôle sur un descripteur de fichier.
Remarques
- La fonction fcntl() doit effectuer les opérations décrites ci-dessous sur les fichiers ouverts. Le paramètre fildes est un descripteur de fichier.
- Les valeurs disponibles pour cmd sont définies dans <fcntl.h> et sont les suivantes :
- Les valeurs suivantes pour cmd sont disponibles pour le verrouillage d'enregistrement consultatif. Le verrouillage d'enregistrement est pris en charge pour les fichiers standard et peut l'être pour d'autres fichiers.
- Des valeurs supplémentaires définies par l'implémentation pour cmd peuvent être définies dans <fcntl.h>. Leurs noms doivent commencer par F_.
- Lorsqu'un verrou partagé est placé sur un segment d'un fichier, les autres processus doivent pouvoir placer des verrous partagés sur ce segment ou une partie de celui-ci. Un verrou partagé empêche tout autre processus de placer un verrou exclusif sur toute partie de la zone protégée. Une demande de verrou partagé échouera si le descripteur de fichier n'a pas été ouvert en lecture.
- Un verrou exclusif empêche tout autre processus de placer un verrou partagé ou exclusif sur toute partie de la zone protégée. Une demande de verrou exclusif échouera si le descripteur de fichier n'a pas été ouvert en écriture.
- La structure flock décrit le type (l_type), le déplacement de départ (l_whence), le déplacement relatif (l_start), la taille (l_len) et l'identifiant de processus (l_pid) du segment du fichier concerné.
- La valeur de l_whence est SEEK_SET, SEEK_CUR ou SEEK_END, pour indiquer que le déplacement relatif en octets de l_start doit être mesuré à partir du début du
fichier, de la position actuelle ou de la fin du fichier, respectivement. La valeur de l_len correspond au nombre d'octets consécutifs à verrouiller. Elle peut être
négative (la définition de off_t autorisant des valeurs négatives pour l_len). Le champ l_pid est utilisé uniquement avec F_GETLK pour renvoyer l'identifiant du
processus détenant un verrou bloquant. Après une requête F_GETLK réussie, lorsqu'un verrou bloquant est trouvé, les valeurs renvoyées dans la structure flock sont
les suivantes :
Constante Description l_type Type de verrou bloquant trouvé. l_whence SEEK_SET. l_start Début du verrou bloquant. l_len Longueur du verrou bloquant. l_pid Identifiant du processus détenant le verrou bloquant. - Si la commande est F_SETLKW et que le processus doit attendre qu'un autre processus libère un verrou, la plage d'octets à verrouiller doit être déterminée avant le blocage de la fonction fcntl(). Si la taille du fichier ou le déplacement de recherche du descripteur de fichier change pendant le blocage de fcntl(), cela n'affecte pas la plage d'octets verrouillés.
- Si l_len est positif, la zone affectée doit commencer à l_start et se terminer à l_start + l_len -1. Si l_len est négatif, la zone affectée doit commencer à l_start + l_len et se terminer à l_start -1. Les verrous peuvent commencer et s'étendre au-delà de la fin actuelle d'un fichier, mais ne doivent pas s'étendre avant le début du fichier. Un verrou doit être défini pour s'étendre jusqu'à la plus grande valeur possible du décalage de fichier pour ce fichier en définissant l_len à 0. Si un tel verrou a également l_start à 0 et l_whence à SEEK_SET, l'ensemble du fichier doit être verrouillé.
- Il ne doit y avoir qu'un seul type de verrou défini pour chaque octet du fichier. Avant le retour réussi d'une requête F_SETLK ou F_SETLKW lorsque le processus appelant possède déjà des verrous sur des octets de la région spécifiée par la requête, le type de verrou précédent pour chaque octet de la région spécifiée doit être remplacé par le nouveau type. Comme indiqué précédemment dans les descriptions des verrous partagés et exclusifs, une requête F_SETLK ou F_SETLKW (respectivement) doit échouer ou se bloquer lorsqu'un autre processus possède déjà des verrous sur des octets de la région spécifiée et que le type de l'un de ces verrous est en conflit avec celui spécifié dans la requête.
- Tous les verrous associés à un fichier pour un processus donné doivent être supprimés lorsqu'un descripteur de fichier de ce fichier est fermé par ce processus ou que le processus détenant ce descripteur de fichier se termine. Les verrous ne sont pas hérités par un processus enfant.
- Un blocage peut survenir si un processus contrôlant une région verrouillée est mis en veille en tentant de verrouiller la région verrouillée d'un autre processus. Si le système détecte que la mise en veille jusqu'au déverrouillage d'une région verrouillée provoquerait un blocage, fcntl() échouera avec une erreur EDEADLK.
- Une requête de déverrouillage (F_UNLCK) dont l_len est différent de zéro et dont le décalage du dernier octet du segment demandé est la valeur maximale pour un objet de type off_t, lorsque le processus possède un verrou existant dont l_len est égal à 0 et incluant le dernier octet du segment demandé, sera traitée comme une requête de déverrouillage à partir du début du segment demandé avec l_len égal à 0. Sinon, une requête de déverrouillage (F_UNLCK) tentera de déverrouiller uniquement le segment demandé.
- Lorsque le descripteur de fichier fildes fait référence à un objet de mémoire partagée, le comportement de fcntl() sera identique à celui d'un fichier standard, à l'exception de l'effet des valeurs suivantes pour le paramètre cmd : F_SETFL, F_GETLK, F_SETLK et F_SETLKW.
- Si fildes fait référence à un objet mémoire typé, le résultat de la fonction fcntl() n'est pas spécifié.
Constante | Description |
---|---|
F_DUPFD | Renvoie un nouveau descripteur de fichier devant être alloué, à la différence près qu'il doit s'agir du descripteur de fichier disponible portant le plus petit numéro, supérieur ou égal au troisième argument, arg, pris comme un entier de type int. Le nouveau descripteur de fichier doit faire référence à la même description de fichier ouvert que le descripteur de fichier d'origine et doit partager les verrous éventuels. L'indicateur FD_CLOEXEC associé au nouveau descripteur de fichier doit être désactivé pour maintenir le fichier ouvert lors des appels à l'une des fonctions exécutables. |
F_DUPFD_CLOEXEC | Similaire à F_DUPFD, mais l'indicateur FD_CLOEXEC associé au nouveau descripteur de fichier doit être activé. |
F_GETFD | Récupère les indicateurs de descripteur de fichier définis dans <fcntl.h> et associés au descripteur de fichier fildes. Les indicateurs de descripteur de fichier sont associés à un seul descripteur de fichier et n'affectent pas les autres descripteurs de fichier faisant référence au même fichier. |
F_SETFD | Définit les indicateurs de descripteur de fichier définis dans <fcntl.h> et associés à fildes avec le troisième paramètre, arg, de type int. Si l'indicateur FD_CLOEXEC du troisième argument est égal à 0, le descripteur de fichier reste ouvert lors des fonctions exécutables ; sinon, il est fermé après l'exécution réussie de l'une d'elles. |
F_GETFL | Récupère les indicateurs d'état et les modes d'accès aux fichiers, définis dans <fcntl.h>, pour la description de fichier associée à fildes. Les modes d'accès aux fichiers peuvent être extraits de la valeur de retour à l'aide du masque O_ACCMODE, défini dans <fcntl.h>. Les indicateurs d'état et les modes d'accès aux fichiers sont associés à la description du fichier et n'affectent pas les autres descripteurs de fichiers faisant référence au même fichier avec des descriptions de fichiers ouverts différentes. Les indicateurs renvoyés peuvent inclure des indicateurs d'état de fichier non standard, non définis par l'application, à condition que ces indicateurs supplémentaires ne modifient pas le comportement d'une application conforme. |
F_SETFL | Définit les indicateurs d'état de fichier, définis dans <fcntl.h>, pour la description de fichier associée à fildes à partir des bits correspondants du troisième argument, arg, de type int. Les bits correspondant au mode d'accès au fichier et aux indicateurs de création de fichier, définis dans <fcntl.h>, définis dans arg, doivent être ignorés. Si des bits de arg autres que ceux mentionnés ici sont modifiés par l'application, le résultat n'est pas spécifié. Si fildes ne prend pas en charge les opérations non bloquantes, il n'est pas spécifié si l'indicateur O_NONBLOCK sera ignoré. |
F_GETOWN | Si fildes fait référence à un socket, obtenir l'ID de processus ou l'ID de groupe de processus spécifié pour recevoir les signaux SIGURG lorsque des données hors bande sont disponibles. Les valeurs positives doivent indiquer un ID de processus ; les valeurs négatives, autres que -1, doivent indiquer un ID de groupe de processus ; la valeur zéro doit indiquer qu'aucun signal SIGURG n'est envoyé. Si fildes ne fait pas référence à un socket, les résultats ne sont pas spécifiés. |
F_SETOWN | Si fildes fait référence à un socket, définir l'ID de processus ou l'ID de groupe de processus spécifié pour recevoir les signaux SIGURG lorsque des données hors bande sont disponibles, en utilisant la valeur du troisième paramètre, arg, de type int. Les valeurs positives doivent indiquer un ID de processus ; les valeurs négatives, autres que -1, doivent indiquer un ID de groupe de processus ; la valeur zéro doit indiquer qu'aucun signal SIGURG n'est envoyé. Chaque fois qu'un signal SIGURG est envoyé au processus ou au groupe de processus spécifié, des vérifications d'autorisations équivalentes à celles effectuées par kill() doivent être effectuées, comme si kill() était appelé par un processus possédant les mêmes identifiants utilisateur réel, effectif et privilèges que le processus appelant fcntl() au moment de l'appel ; si l'appel kill() échoue, aucun signal ne doit être envoyé. Ces vérifications d'autorisations peuvent également être effectuées par l'appel fcntl(). Si le processus spécifié par arg se termine ultérieurement, ou si le groupe de processus spécifié par arg devient vide, tout en étant spécifié pour recevoir des signaux SIGURG lorsque des données hors bande sont disponibles depuis fildes, aucun signal ne doit être envoyé aux processus créés ultérieurement possédant le même identifiant ou groupe de processus, quelles que soient les autorisations ; il n'est pas précisé si cela est réalisé par l'équivalent d'un appel fcntl(fildes, F_SETOWN, 0) au moment où le processus se termine ou est attendu, ou si le groupe de processus devient vide, ou par d'autres moyens. Si fildes ne fait pas référence à un socket, les résultats ne sont pas spécifiés. |
Constante | Description |
---|---|
F_GETLK | Récupère tout verrou bloquant la description de verrou pointée par le troisième paramètre, arg, considéré comme un pointeur vers le type struct flock, défini dans <fcntl.h>. Les informations récupérées écrasent celles transmises à fcntl() dans la structure flock. Si aucun verrou empêchant sa création n'est trouvé, la structure reste inchangée, à l'exception du type de verrou, défini sur F_UNLCK. |
F_SETLK | Définit ou supprime un verrou de segment de fichier selon la description de verrou pointée par le troisième argument, arg, considéré comme un pointeur vers le type struct flock, défini dans |
F_SETLKW | Cette commande est équivalente à F_SETLK, sauf que si un verrou partagé ou exclusif est bloqué par d'autres verrous, le processus léger attend que la requête soit satisfaite. Si un signal à intercepter est reçu pendant que fcntl() attend une région, fcntl() est interrompu. Au retour du gestionnaire de signaux, fcntl() renvoie -1 avec errno défini sur [EINTR], et l'opération de verrouillage n'est pas exécutée. |
Erreurs
La fonction fcntl() échouera si :
Constante | Description |
---|---|
EACCES ou EAGAIN | Le paramètre cmd est F_SETLK ; le type de verrou (l_type) est un verrou partagé (F_RDLCK) ou exclusif (F_WRLCK) et le segment de fichier à verrouiller est déjà verrouillé de manière exclusive par un autre processus, ou le type est un verrou exclusif et une partie du segment de fichier à verrouiller est déjà verrouillée de manière partagée ou exclusive par un autre processus. |
EBADF | Le paramètre fildes n'est pas un descripteur de fichier ouvert valide, ou le paramètre cmd est F_SETLK ou F_SETLKW, le type de verrou, l_type, est un verrou partagé (F_RDLCK) et fildes n'est pas un descripteur de fichier ouvert en lecture, ou le type de verrou, l_type, est un verrou exclusif (F_WRLCK) et fildes n'est pas un descripteur de fichier ouvert en écriture. |
EINTR | Le paramètre cmd est F_SETLKW et la fonction a été interrompue par un signal. |
EINVAL | Le paramètre cmd est invalide, ou le paramètre cmd est F_DUPFD ou F_DUPFD_CLOEXEC et arg est négatif ou supérieur ou égal à {OPEN_MAX}, ou le paramètre cmd est F_GETLK, F_SETLK ou F_SETLKW et les données pointées par arg ne sont pas valides, ou fildes fait référence à un fichier qui ne prend pas en charge le verrouillage. |
EMFILE | Le paramètre cmd est F_DUPFD ou F_DUPFD_CLOEXEC et tous les descripteurs de fichiers disponibles pour le processus sont actuellement ouverts, ou aucun descripteur de fichier supérieur ou égal à arg n'est disponible. |
ENOLCK | Le paramètre cmd est F_SETLK ou F_SETLKW et la satisfaction de la requête de verrouillage ou de déverrouillage entraînerait un nombre de régions verrouillées dans le système dépassant la limite imposée par le système. |
EOVERFLOW | L'une des valeurs à renvoyer ne peut pas être représentée correctement. |
EOVERFLOW | Le paramètre cmd est F_GETLK, F_SETLK ou F_SETLKW et le plus petit ou, si l_len est différent de zéro, le plus grand décalage d'un octet du segment demandé ne peut pas être représenté correctement dans un objet de type off_t. |
ESRCH | Le paramètre cmd est F_SETOWN et aucun processus ou groupe de processus correspondant à celui spécifié par arg n'est trouvé. |
La fonction fcntl() peut échouer si :
Constante | Description |
---|---|
EDEADLK | Le paramètre cmd est F_SETLKW, le verrou est bloqué par un verrou d'un autre processus et la mise en veille du processus appelant en attendant que ce verrou soit libéré provoquerait un blocage. |
EINVAL | Le paramètre cmd est F_SETOWN et sa valeur n'est pas valide comme identifiant de processus ou de groupe de processus. |
EPERM | Le paramètre cmd est F_SETOWN et le processus appelant n'a pas l'autorisation d'envoyer un signal SIGURG à un processus spécifié par arg. |
Exemples
L'exemple suivant montre comment placer un verrou sur les octets 100 à 109 d'un fichier, puis le supprimer ultérieurement. F_SETLK permet d'effectuer une requête de verrouillage non bloquante afin que le processus n'ait pas à attendre si un verrou incompatible est détenu par un autre processus ; il peut alors effectuer une autre action.
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <stdio.h>
-
- int main(int argc, char *argv[]) {
- int fd;
- struct flock fl;
-
-
- fd = open("testfile", O_RDWR);
- if (fd == -1)
- /* Erreur de descripteur */;
-
-
- /* Effectuez une demande non bloquante pour placer un verrou en écriture sur les octets 100 à 109 du fichier de test */
-
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 100;
- fl.l_len = 10;
-
-
- if (fcntl(fd, F_SETLK, &fl) == -1) {
- if (errno == EACCES || errno == EAGAIN) {
- printf("Déjà verrouillé par un autre processus\n");
-
-
- /* Nous ne pouvons pas obtenir le verrou pour le moment */
-
-
- } else {
- /* Gérer les erreurs inattendues */;
- }
- } else { /* Le verrouillage a été accordé... */
-
-
- /* Effectuer des entrées/sorties sur les octets 100 à 109 du fichier */
-
-
- /* Déverrouiller les octets verrouillés */
-
- fl.l_type = F_UNLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 100;
- fl.l_len = 10;
- if (fcntl(fd, F_SETLK, &fl) == -1)
- /* Erreur de descripteur */;
- }
- exit(EXIT_SUCCESS);
- } /* main */
L'exemple suivant montre comment définir l'indicateur de fermeture à l'exécution pour le descripteur de fichier fd :
- #include <unistd.h>
- #include <fcntl.h>
- ...
- int flags;
-
-
- flags = fcntl(fd, F_GETFD);
- if (flags == -1)
- /* Erreur de descripteur */;
- flags |= FD_CLOEXEC;
- if (fcntl(fd, F_SETFD, flags) == -1)
- /* Erreur de descripteur */;
Voir également
alarm, close, exec, kill, open, sigaction