OPEN

Section : Manuel du programmeur Linux (2)
Mise à jour de la version anglaise : 4 juillet 2008
Index Menu principal  

NOM

open, creat - Ouvrir ou créer éventuellement un fichier ou un périphérique  

SYNOPSIS

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

int creat(const char *pathname, mode_t mode);
 

DESCRIPTION

Étant donné le chemin pathname d'un fichier, open() renvoie un descripteur de fichier, un petit entier positif ou nul utilisable par des appels système ultérieurs (read(2), write(2), lseek(2), fcntl(2), etc.). Le descripteur de fichier renvoyé par un appel réussi sera le plus petit descripteur de fichier non encore ouvert pour le processus.

Par défaut, le nouveau descripteur de fichier est configuré pour rester ouvert au travers d'un execve(2) (c'est-à-dire que l'attribut FD_CLOEXEC du descripteur de fichier, décrit dans fcntl(2), est initialement désactivé ; l'attribut O_CLOEXEC, spécifique à Linux, peut être utilisé pour modifier ce comportement par défaut ). Le pointeur de position dans le fichier est placé à son début (voir lseek(2)).

Un appel à open() crée une nouvelle description de fichier ouvert, une entrée dans la table des fichiers ouverts du système. Cette entrée enregistre la position dans le fichier et les attributs d'état du fichier (modifiable via l'opération F_SETFL de fcntl(2)). Un descripteur de fichier est une référence à l'une de ces entrées ; cette référence n'est pas affectée si pathname est ultérieurement supprimé ou modifié pour se référer à un fichier différent. La nouvelle description de fichier ouvert n'est initialement pas partagée avec un autre processus, mais ce partage peut survenir après un fork(2).

Le paramètre flags doit inclure l'un des mode d'accès suivants : O_RDONLY, O_WRONLY ou O_RDWR. Ceux-ci réclament respectivement l'ouverture du fichier en lecture seule, écriture seule, ou lecture-écriture. À cette valeur peut être ajouté zéro ou plusieurs attributs de création de fichier et attributs d'état de fichier avec un OU binaire. Les attributs de création de fichier sont O_CREAT, O_EXCL, O_NOCTTY et O_TRUNC. Les attributs d'état de fichier sont tous les autres attributs restant listés plus loin. La différence entre ces deux groupes d'attributs est que l'on peut récupérer et (dans certains cas) modifier avec fcntl(2) les attributs d'état de fichier. La liste complète des attributs de création de fichier et des attributs d'état de fichier est la suivante :

O_APPEND
Le fichier est ouvert en mode « ajout ». Initialement, et avant chaque write(2), la tête de lecture/écriture est placée à la fin du fichier comme avec lseek(2). Il y a un risque d'endommager le fichier lorsque O_APPEND est utilisé, sur un système de fichiers NFS, si plusieurs processus tentent d'ajouter des données simultanément au même fichier. Ceci est dû au fait que NFS ne supporte pas l'opération d'ajout de données dans un fichier, aussi le noyau du client est obligé de la simuler, avec un risque de concurrence des tâches.
O_ASYNC
Activer le pilotage d'entrées-sorties par signal : déclencher un signal (SIGIO par défaut, mais peut être changé via fcntl(2)) lorsque la lecture ou l'écriture deviennent possibles sur ce descripteur. Ceci n'est possible que pour les terminaux, pseudo-terminaux, sockets et (depuis Linux 2.6) tubes et FIFO. Voir fcntl(2) pour plus de détails.
O_CLOEXEC (Depuis Linux 2.6.23)
Activer l'attribut « close-on-exec » pour le nouveau descripteur de fichier. Spécifier cet attribut permet à un programme d'éviter une opération supplémentaire F_SETFD de fcntl(2) pour positionner l'attribut FD_CLOEXEC. De plus, l'utilisation de cet attribut est essentielle dans certains programmes multithreadés puisque l'utilisation d'une opération F_SETFD de fcntl(2) pour positionner l'attribut FD_CLOEXEC ne suffit pas pour éviter les conditions de concurrence lorsqu'un thread ouvre un descripteur de fichier en même temps qu'un autre thread effectue un fork(2) plus un execve(2).
O_CREAT
Créer le fichier s'il n'existe pas. Le possesseur (UID) du fichier est renseigné avec l'UID effectif du processus. Le groupe propriétaire (GID) du fichier est le GID effectif du processus ou le GID du répertoire parent (ceci dépend du système de fichiers, des options de montage, du mode du répertoire parent, etc.). Voir par exemple les options de montage bsdgroups et sysvgroups décrites dans la page mount(8)).

mode indique les permissions à utiliser si un nouveau fichier est créé. Cet argument doit être fourni lorsque O_CREAT est spécifié dans flags ; si O_CREAT n'est pas spécifié, mode est ignoré. Les permissions effectives sont modifiées par l'umask du processus de manière classique : les permissions du fichier créé sont (mode & ~umask). Veuillez noter que ce mode ne s'applique qu'aux accès ultérieurs au fichier nouvellement créé. L'appel open() qui crée un fichier dont le mode est en lecture seule fournira quand même un descripteur de fichier en lecture et écriture.

Les constantes symboliques suivantes sont disponibles pour mode :

S_IRWXU
00700 L'utilisateur (propriétaire du fichier) a les autorisations de lecture, écriture, exécution.
S_IRUSR
00400 L'utilisateur a l'autorisation de lecture.
S_IWUSR
00200 L'utilisateur a l'autorisation d'écriture.
S_IXUSR
00100 L'utilisateur a l'autorisation d'exécution.
S_IRWXG
00070 Le groupe a les autorisations de lecture, écriture, exécution.
S_IRGRP
00040 Le groupe a l'autorisation de lecture.
S_IWGRP
00020 Le groupe a l'autorisation d'écriture.
S_IXGRP
00010 Le groupe a l'autorisation d'exécution.
S_IRWXO
00007 Tout le monde a les autorisations de lecture, écriture, exécution.
S_IROTH
00004 Tout le monde a l'autorisation de lecture.
S_IWOTH
00002 Tout le monde a l'autorisation d'écriture.
S_IXOTH
00001 Tout le monde a l'autorisation d'exécution.
O_DIRECT (Depuis Linux 2.4.10)
Essayer de minimiser les effets du cache d'entrée-sortie sur ce fichier. Ceci dégradera en général les performances, mais est utilisé dans des situations spéciales, lorsque les applications ont leur propres caches. Les entrées-sorties dans le fichier se font directement depuis l'espace utilisateur, elles sont synchrones (à la fin de read(2) ou write(2), les données ont obligatoirement été transférées). Voir NOTES plus loin pour une discussion approfondie.

Une interface à la sémantique similaire (mais dépréciée) pour les périphériques de type bloc est décrite à la page raw(8).

O_DIRECTORY
Si pathname n'est pas un répertoire, l'ouverture échoue. Cet attribut est spécifique à Linux et fut ajouté dans la version 2.1.126 du noyau, pour éviter des problèmes de dysfonctionnement si opendir(3) est invoqué sur une FIFO ou un périphérique de bande. Cet attribut ne devrait jamais être utilisé ailleurs que dans l'implémentation de opendir(3).
O_EXCL
S'assurer que cet appel crée le fichier : si cet attribut est spécifié en conjonction avec O_CREAT et si le fichier pathname existe déjà, open() échouera. Le comportement de O_EXCL est indéterminé si O_CREAT n'est pas spécifié.

Lorsque ces deux attributs sont spécifiés, les liens symboliques ne sont pas suivis : si pathname est un lien symbolique, open() échouera quelque soit l'endroit où pointe le lien symbolique.

O_EXCL n'est pas pris en charge sur les systèmes de fichiers NFS version 2 (NFSv2) ou sous Linux avant le noyau 2.6. Il est pris en charge depuis Linux 2.6 avec NFSv3 ou plus récent. Dans les environnements où la prise en charge de O_EXCL pour NFS n'est pas fournie, les programmes qui ont besoin de cette fonctionnalité pour verrouiller des tâches risquent de rencontrer une concurrence critique (race condition). Les programmes portables qui veulent effectuer un verrouillage fichier atomique en utilisant un fichier verrou et qui doivent éviter la dépendance de la prise en charge NFS pour O_EXCL peuvent créer un fichier unique sur le même système de fichiers (par exemple, avec le PID et le nom de l'hôte), et utiliser link(2) pour créer un lien sur un fichier de verrouillage. Si link(2) renvoie 0, le verrouillage est réussi. Sinon, utilisez stat(2) sur ce fichier unique pour vérifier si le nombre de liens a augmenté jusqu'à 2, auquel cas le verrouillage est également réussi.

O_LARGEFILE
(LFS) (Ndt : Large Files System) Autoriser l'ouverture des fichiers dont la taille ne peut pas être représentée avec un off_t (mais qui peut l'être avec un off64_t). La macro _LARGEFILE64_SOURCE doit être définie afin d'obtenir cette définition. Donner la valeur 64 à la macro de test de fonctionnalité (plutôt que d'utiliser O_LARGEFILE) _FILE_OFFSET_BITS est la méthode préférée pour accéder à de gros fichiers sur les systèmes 32 bits (voir feature_test_macros(7)).
O_NOATIME (Depuis Linux 2.6.8)
Ne pas mettre à jour l'horodatage du dernier accès au fichier (st_atime dans l'inœud) lorsque celui-ci est lu avec read(2). Cet attribut existe pour les programmes d'indexation ou de sauvegarde où son utilisation peut réduire de manière significative l'activité sur le disque. Cet attribut peut ne pas exister sur tous les systèmes de fichiers. Un exemple est NTFS où le serveur maintient l'horodatage d'accès
O_NOCTTY
Si pathname correspond à un périphérique de terminal --- voir tty(4) ---, il ne deviendra pas le terminal contrôlant le processus même si celui-ci n'est attaché à aucun autre terminal.
O_NOFOLLOW
Si pathname est un lien symbolique, l'ouverture échoue. Ceci est une extension FreeBSD, qui fut ajoutée à Linux dans la version 2.1.126. Les liens symboliques se trouvant dans le chemin d'accès proprement dit seront suivis normalement.
O_NONBLOCK ou O_NDELAY
Le fichier est ouvert en mode « non bloquant ». Ni la fonction open() ni aucune autre opération ultérieure sur ce fichier ne laissera le processus appelant en attente. Pour la manipulation des FIFO (tubes nommés), voir également fifo(7). Pour une discussion sur l'effet de O_NONBLOCK conjointement aux verrouillages de fichier impératifs et aux baux de fichiers, voir fcntl(2).
O_SYNC
Le fichier est ouvert en écriture synchronisée. Chaque appel à write(2) sur le fichier bloquera le processus appelant jusqu'à ce que les données aient été écrites physiquement sur le support matériel. Mais voir la section NOTES plus bas.
O_TRUNC
Si le fichier existe, est un fichier régulier, et est ouvert en écriture (O_RDWR ou O_WRONLY), il sera tronqué à une longueur nulle. Si le fichier est une FIFO ou un périphérique terminal, l'attribut O_TRUNC est ignoré. Sinon, le comportement de O_TRUNC n'est pas précisé. Sur de nombreuses versions de Linux, il sera ignoré ; sur d'autres versions il déclenchera une erreur).

Certains de ces attributs optionnels peuvent être modifiés par la suite avec la fonction fcntl(2).

creat() est équivalent à open() avec l'attribut flags égal à O_CREAT | O_WRONLY | O_TRUNC .  

VALEUR RENVOYÉE

open() et creat() renvoient le nouveau descripteur de fichier s'ils réussissent, ou -1 s'ils échouent, auquel cas errno contient le code d'erreur.  

ERREURS

EACCES
L'accès demandé au fichier est interdit, ou la permission de parcours pour l'un des répertoires du chemin pathname est refusée, ou le fichier n'existe pas encore et le répertoire parent ne permet pas l'écriture. (Voir aussi path_resolution(7).)
EEXIST
pathname existe déjà et O_CREAT et O_EXCL ont été indiqués.
EFAULT
pathname pointe en dehors de l'espace d'adressage accessible.
EFBIG
pathname fait référence à un fichier régulier, trop grand pour pouvoir être ouvert - voir O_LARGEFILE plus haut (POSIX.1-2001 spécifie l'erreur EOVERFLOW pour ce cas).
EINTR
Pendant qu'il était bloqué en attente de l'ouverture d'un périphérique lent (par exemple, une FIFO ; voir fifo(7)), l'appel a été interrompu par un gestionnaire de signal ; voir signal(7).
EISDIR
On a demandé une écriture alors que pathname correspond à un répertoire (en fait, O_WRONLY ou O_RDWR ont été demandés).
ELOOP
pathname contient une référence circulaire (à travers un lien symbolique), ou l'attribut O_NOFOLLOW est indiqué et pathname est un lien symbolique.
EMFILE
Le processus a déjà ouvert le nombre maximal de fichiers.
ENAMETOOLONG
pathname est trop long.
ENFILE
La limite du nombre total de fichiers ouverts sur le système a été atteinte.
ENODEV
pathname correspond à un fichier spécial et il n'y a pas de périphérique correspondant.
ENOENT
O_CREAT est absent et le fichier n'existe pas. Ou un répertoire du chemin d'accès pathname n'existe pas, ou est un lien symbolique pointant nulle part.
ENOMEM
Pas assez de mémoire pour le noyau.
ENOSPC
pathname devrait être créé mais le périphérique concerné n'a plus assez de place pour un nouveau fichier.
ENOTDIR
Un élément du chemin d'accès pathname n'est pas un répertoire, ou l'attribut O_DIRECTORY est utilisé et pathname n'est pas un répertoire.
ENXIO
O_NONBLOCK | O_WRONLY est indiqué, le fichier est une FIFO et le processus n'a pas de fichier ouvert en lecture. Ou le fichier est un nœud spécial et il n'y a pas de périphérique correspondant.
EPERM
L'attribut O_NOATIME a été fourni, mais l'UID effectif de l'appelant ne correspond pas à celui du propriétaire du fichier et l'appelant n'est pas privilégié (CAP_FOWNER).
EROFS
Un accès en écriture est demandé alors que pathname réside sur un système de fichiers en lecture seule.
ETXTBSY
On a demandé une écriture alors que pathname correspond à un fichier exécutable actuellement utilisé.
EWOULDBLOCK
L'attribut O_NONBLOCK a été spécifié et un bail incompatible est détenu sur le fichier (voir fcntl(2)).
 

CONFORMITÉ

SVr4, BSD 4.3, POSIX.1-2001. Les attributs O_DIRECTORY, O_NOATIME et O_NOFOLLOW sont spécifiques à Linux et il faut définir la constante symbolique _GNU_SOURCE pour avoir leurs définitions.

L'attribut O_CLOEXEC n'est pas spécifié par POSIX.1-2001, mais il est prévu de l'inclure dans la prochaine révision de la norme ; il faut définir la macro _GNU_SOURCE pour obtenir sa définition.

O_DIRECT n'est pas spécifié par POSIX ; il faut définir la constante symbolique _GNU_SOURCE pour obtenir sa définition.  

NOTES

Sous Linux, le drapeau O_NONBLOCK indique que l'on veut ouvrir mais pas nécessairement dans l'intention de lire ou d'écrire. Il est typiquement utilisé pour ouvrir des périphériques dans le but de récupérer un descripteur de fichier pour l'utiliser avec ioctl(2).

Contrairement aux autres valeurs qui peuvent être indiquées dans flags, les valeurs du mode d'accès O_RDONLY, O_WRONLY et O_RDWR ne sont pas des bits individuels. Ils définissent l'ordre des deux bits de poids faible de flags, et ont pour valeur respective 0, 1 et 2. En d'autres mots, la combinaison O_RDONLY | O_WRONLY est une erreur logique et n'a certainement pas la même signification que O_RDWR.

Linux réserve le mode d'accès, particulier et non standard, mode 3 (11 en binaire) à flags pour signifier : vérifier les permissions de lecture et d'écriture du fichier et renvoyer un descripteur de fichier qui ne pourra pas être utilisé pour une lecture ou une écriture. Ce mode d'accès non standard est utilisé par certains pilotes Linux pour renvoyer un descripteur qui ne sera utilisé que par des opérations ioctl(2) spécifiques au périphérique. L'effet (indéfini) de O_RDONLY | O_TRUNC varie suivant les implémentations. Sur de nombreux systèmes, le fichier est effectivement tronqué.

Plusieurs problèmes se posent avec le protocole NFS, concernant entre autres O_SYNC et O_NDELAY.

POSIX fournit trois variantes différentes des entrées-sorties synchronisées correspondant aux attributs O_SYNC, O_DSYNC et O_RSYNC. Actuellement (2.1.130), elles sont toutes équivalentes sous Linux. Notez que open() peut ouvrir des fichiers spéciaux mais creat() ne peut pas en créer, il faut utiliser mknod(2) à la place.

Sur les systèmes de fichiers NFS, où la correspondance d'UID est activée, open() peut renvoyer un descripteur de fichier alors qu'une requête read(2) par exemple sera refusée avec le code d'erreur EACCES. En effet, c'est parce que le client a effectué open() en vérifiant les autorisations d'accès, mais la correspondance d'UID est calculée par le serveur au moment des requêtes de lecture ou d'écriture.

Si un fichier est créé, ses horodatages st_atime, st_ctime, st_mtime (respectivement horodatage du dernier accès, horodatage du dernier changement d'état, horodatage de la dernière modification ; voir stat(2)) sont fixés à l'heure actuelle, ainsi que les champs st_ctime et st_mtime du répertoire parent. Sinon, si le fichier est modifié à cause de l'attribut O_TRUNC, ses champs st_ctime et st_mtime sont remplis avec l'heure actuelle.  

O_DIRECT

L'attribut O_DIRECT peut imposer des restrictions d'alignement sur la longueur et l'adresse des tampons en espace utilisateur et sur la tête de lecture des E/S. Pour l'alignement Linux, les restrictions varient suivant le système de fichiers et la version du noyau et peuvent être complètement absentes. Toutefois, il n'y a actuellement aucune interface, indépendante du système de fichiers, permettant à une application de connaître ces restrictions pour un fichier ou système de fichiers donné. Certains systèmes de fichiers fournissent leur propore interface pour le faire, comme par exemple l'opération XFS_IOC_DIOINFO de xfsctl(3).

Sous Linux 2.4, la taille des transferts, l'alignement d'un tampon utilisateur et la position dans le fichier doivent être des multiples de la taille de bloc logique du système de fichiers. Sous Linux 2.6, un alignement sur des frontières 512 octets suffit.

L'attribut O_DIRECT a été introduit par SGI IRIX, qui a des restrictions d'alignement identiques à celles de Linux 2.4. IRIX a aussi un appel fcntl(2) pour obtenir les alignements et tailles appropriés. FreeBSD 4.x a introduit un attribut du même nom, mais sans les restrictions d'alignement.

La prise en charge de O_DIRECT a été ajoutée dans Linux 2.4.10. Les noyaux plus anciens ignorent simplement cet attribut. Certains systèmes de fichiers peuvent ne pas implémenter l'attribut et open() échouera avec l'erreur EINVAL s'il est utilisé.

Les applications devraient éviter le mélange de l'utilisation de O_DIRECT et des E/S normales sur le même fichier, particulièrement pour le chevauchement de régions d'octet dans le même fichier. Même si le système de fichiers gère correctement les problèmes de cohésion dans cette situation, le trafic d'E/S sera probablement plus lent que si l'un des modes seulement est utilisé. De la même manière, les applications devraient éviter le mélange de l'utilisation de mmap(2) avec des E/S directes sur le même fichier.

Le comportement de O_DIRECT avec NFS diffère des systèmes de fichiers locaux. Les anciens noyaux, ou les noyaux configurés de certaines manières, peuvent ne pas prendre en charge cette combinaison. Le protocole NFS ne prend pas en charge le passage de l'attribut vers le serveur, aussi les E/S O_DIRECT court-circuiteront le cache de pages sur le client ; le serveur peut conserver en cache les E/S. Le client demande au serveur de réaliser des E/S synchrones afin de préserver la sémantique synchrone de O_DIRECT. Certains serveurs seront peu performants dans ces circonstances, particulièrement si la taille des E/S est petite. Certains serveurs peuvent également être configurés pour mentir au client à propos de l'arrivée d'E/S à un stockage stable ; ceci permet d'éviter de réduire la performance mais fait courrir des risques en cas de coupure de l'alimentation du serveur. Le client NFS Linux ne place aucune restriction d'alignement sur les E/S O_DIRECT.

En résumé, O_DIRECT est un outil potentiellement puissant qui devrait être utilisé avec précaution. Il est recommandé que les applications considèrent l'utilisation de O_DIRECT comme une option de performance qui est déactivée par défaut.

« Ce qui m'a toujours dérangé avec O_DIRECT est que toute l'interface est stupide et a probablement été conçue par un singe dérangé, sous l'influence de substances psychotropes puissantes ». -- Linus.
 

BOGUES

Actuellement, il n'est pas possible d'activer le pilotage d'entrées-sorties par signal en spécifiant O_ASYNC lors d'un appel à open() ; utilisez fcntl(2) pour activer cet attribut.  

VOIR AUSSI

chmod(2), chown(2), close(2), dup(2), fcntl(2), link(2), lseek(2), mknod(2), mmap(2), mount(2), openat(2), read(2), socket(2), stat(2), umask(2), unlink(2), write(2), fopen(3), feature_test_macros(7), fifo(7), path_resolution(7), symlink(7)  

TRADUCTION

Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 15 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 open ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.

 

Index

NOM
SYNOPSIS
DESCRIPTION
VALEUR RENVOYÉE
ERREURS
CONFORMITÉ
NOTES
O_DIRECT
BOGUES
VOIR AUSSI
TRADUCTION

Dernière mise à jour : 17 juillet 2008