open(2) System Calls Manual open(2) NOM open, openat, creat - Ouvrir ou creer eventuellement un fichier BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include int open(const char *pathname, int flags, ... /* mode_t mode */ ); int creat(const char *pathname, mode_t mode); int openat(int dirfd, const char *pathname, int flags, ... /* mode_t mode */ ); /* Documente a part, dans openat2(2) : */ int openat2(int dirfd, const char *pathname, const struct open_how *how, size_t size); Exigences de macros de test de fonctionnalites pour la glibc (consulter feature_test_macros(7)) : openat() : Depuis la glibc 2.10 : _POSIX_C_SOURCE >= 200809L avant la glibc 2.10 : _ATFILE_SOURCE DESCRIPTION L'appel systeme open() ouvre le fichier indique par pathname. S'il n'existe pas, il peut (si O_CREAT est indique dans flags) etre cree par open(). La valeur renvoyee par open() est un descripteur de fichier, un petit entier positif ou nul qui est un indice d'entree dans la table de processus de descripteurs de fichiers ouverts. Le descripteur de fichier est ensuite utilise dans d'autres appels systeme (read(2), write(2), lseek(2), fcntl(2), etc.) pour se referer au fichier ouvert. Le descripteur de fichier renvoye par un appel reussi sera celui du plus petit numero de descripteur de fichier non actuellement ouvert par le processus. Par defaut, le nouveau descripteur de fichier est configure pour rester ouvert apres un appel a execve(2) (son attribut FD_CLOEXEC decrit dans fcntl(2) est initialement desactive). L'attribut O_CLOEXEC decrit ci-dessous permet de modifier ce comportement par defaut. La position dans le fichier est definie au debut du fichier (consultez lseek(2)). Un appel a open() cree une nouvelle description de fichier ouvert, une entree dans la table de fichiers ouverts du systeme. Cette description de fichier ouvert enregistre la position dans le fichier et les attributs d'etat du fichier (voir ci-dessous). Un descripteur de fichier est une reference a une description de fichier ouvert ; cette reference n'est pas modifiee si pathname est ensuite supprime ou modifie pour faire reference a un autre fichier. Pour obtenir plus de details sur les descriptions de fichiers ouverts, consultez NOTES. Le parametre flags est l'un des elements O_RDONLY, O_WRONLY ou O_RDWR qui reclament respectivement l'ouverture du fichier en lecture seule, ecriture seule, ou lecture/ecriture. De plus, zero ou plusieurs attributs de creation de fichier et attributs d'etat de fichier peuvent etre indiques dans flags avec un OU binaire. Les attributs de creation de fichier sont O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TMPFILE et O_TRUNC. Les attributs d'etat de fichier sont tous les autres attributs indiques ci-dessous. La distinction entre ces deux groupes est que les attributs d'etat de fichier modifient la semantique de l'operation d'ouverture elle-meme, tandis que les attributs de l'etat du fichier modifient celle des operations d'E/S qui suivent. Les attributs d'etat de fichier peuvent etre lus et (dans certains cas) modifies ; consultez fcntl(2) pour plus de precisions. La liste complete des attributs de creation et d'etat de fichier est la suivante. O_APPEND Le fichier est ouvert en mode << ajout >>. Avant chaque write(2), la tete de lecture/ecriture est placee a la fin du fichier comme avec lseek(2). La modification de la position dans le fichier et l'operation d'ecriture sont effectuees sous forme d'etape atomique unique. Il y a un risque d'endommager le fichier lorsque O_APPEND est utilise, sur un systeme de fichiers NFS, si plusieurs processus tentent d'ajouter des donnees simultanement au meme fichier. Ceci est du au fait que NFS ne gere pas l'operation d'ajout de donnees dans un fichier, aussi le noyau du client est oblige de la simuler, ce qui est impossible sans concurrence des taches. O_ASYNC Declencher un signal (SIGIO par defaut, mais peut etre change via fcntl(2)) lorsque la lecture ou l'ecriture deviennent possibles sur ce descripteur. Ceci n'est possible que pour les terminaux, pseudoterminaux, sockets et (depuis Linux 2.6) tubes et FIFO. Consultez fcntl(2) pour plus de details. Consultez aussi BOGUES ci-dessous. O_CLOEXEC (depuis Linux 2.6.23) Activer l'attribut << close-on-exec >> pour le nouveau descripteur de fichier. En precisant cet attribut, on evite au programme d'avoir a utiliser les operations F_SETFD de fcntl(2) pour positionner l'attribut FD_CLOEXEC. Notez que le recours a cet attribut est indispensable pour certains programmes multithreades. En effet, l'utilisation d'une operation F_SETFD de fcntl(2) pour positionner l'attribut FD_CLOEXEC ne suffit pas a eviter une situation d'acces concurrents si un thread ouvre un descripteur de fichier et tente d'activer l'attribut << close-on-exec >> au moyen de fcntl(2) au moment ou un autre thread execute fork(2) suivi de execve(2). Selon l'ordre dans lequel ces operations s'executent, cette concurrence peut aboutir a ce que le descripteur de fichier renvoye par open() soit involontairement mis a disposition du programme execute par le processus enfant cree par fork(2). (Ce type de concurrence est en principe possible pour tout appel systeme qui cree un descripteur de fichier dont l'attribut << close-on-exec >> est actif ; certains appels systeme de Linux offrent des equivalents de l'attribut O_CLOEXEC pour regler ce probleme.) O_CREAT Si pathname n'existe pas, le creer en tant que fichier normal. Le proprietaire (identifiant utilisateur) du nouveau fichier est positionne sur l'identifiant de l'utilisateur effectif du processus. Le groupe (identifiant de groupe) proprietaire du nouveau fichier est soit positionne sur l'identifiant du groupe effectif du processus (dans la semantique de System V), soit sur celui du repertoire parent (dans la semantique de BSD). Sur Linux, le comportement varie selon que le positionnement du bit set-group-ID sur le repertoire parent : s'il est positionne, la semantique de BSD s'applique, sinon c'est celle de System V. Pour certains de fichiers, le comportement depend aussi des options de montage bsdgroups et sysvgroups decrites dans mount(8). L'argument mode indique les bits du mode du fichier a appliquer lors de la creation d'un nouveau fichier. Si ni O_CREAT, ni O_TMPFILE ne sont indiques dans flags, mode est ignore (et peut ainsi etre indique en tant que 0 voire absent). L'argument mode doit etre fourni si O_CREAT ou O_TMPFILE est indique dans flags ; s'il n'est pas indique, des octets arbitraires de la pile s'appliqueront comme mode du fichier. Le mode effectif est modifie par le umask du processus de maniere classique : en l'absence d'ACL (liste de controle d'acces) par defaut, les droits du fichier cree sont (mode & ~umask). Notez que mode ne s'applique qu'aux acces ulterieurs au fichier nouvellement cree ; l'appel open() qui cree un fichier dont le mode est en lecture seule fournira quand meme un descripteur de fichier en lecture et ecriture. Les constantes symboliques suivantes sont disponibles pour mode : S_IRWXU 00700 L'utilisateur (proprietaire du fichier) a les autorisations de lecture, ecriture, execution. S_IRUSR 00400 L'utilisateur a l'autorisation de lecture. S_IWUSR 00200 L'utilisateur a l'autorisation d'ecriture. S_IXUSR 00100 L'utilisateur a l'autorisation d'execution. S_IRWXG 00070 Le groupe a les autorisations de lecture, ecriture, execution. S_IRGRP 00040 Le groupe a l'autorisation de lecture. S_IWGRP 00020 Le groupe a l'autorisation d'ecriture. S_IXGRP 00010 Le groupe a l'autorisation d'execution. S_IRWXO 00007 Tout le monde a les autorisations de lecture, ecriture, execution. S_IROTH 00004 Tout le monde a l'autorisation de lecture. S_IWOTH 00002 Tout le monde a l'autorisation d'ecriture. S_IXOTH 00001 Tout le monde a l'autorisation d'execution. Selon POSIX, le positionnement des autres bits dans mode n'a pas d'effet specifie. Sur Linux, les bits suivants sont egalement geres dans mode : S_ISUID 0004000 bit set-user-ID. S_ISGID 0002000 bit set-group-ID (voir inode(7)). S_ISVTX 0001000 bit sticky (voir inode(7)). O_DIRECT (depuis Linux 2.4.10) Essayer de minimiser les effets du cache d'entree-sortie sur ce fichier. Cela degradera en general les performances, mais est utile dans des situations speciales, comme lorsque les applications ont leur propre cache. Les entrees-sorties de fichier sont faites directement de et vers les tampons d'espace utilisateur. L'ajout de l'attribut O_DIRECT fait que les entrees-sorties sont synchrones ; en realite un effort est fait pour rendre le transfert synchrone mais cela n'offre pas la garantie fournie par l'attribut O_SYNC que les donnees et metadonnees sont transferees. Pour garantir des entrees-sorties synchrones, l'attribut O_SYNC doit etre utilise en plus de l'attribut O_DIRECT. Consultez la section NOTES ci-dessous. Une interface a la semantique similaire (mais depreciee) pour les peripheriques blocs est decrite dans raw(8). O_DIRECTORY Si pathname n'est pas un repertoire, l'ouverture echoue. Cet attribut fut ajoute dans Linux 2.1.126, pour eviter des problemes de dysfonctionnement si opendir(3) est invoque sur une FIFO ou un peripherique a bande. O_DSYNC Les operations d'ecriture dans le fichier se derouleront selon les conditions d'execution des operations E/S synchrones avec garantie d'integrite des donnees. Au moment ou write(2) (ou un appel similaire) renvoie une donnee, elle a ete transmise au materiel sur lequel s'execute l'appel, avec toutes les metadonnees du fichier qui pourraient etre necessaires a la recuperation de cette donnee (c'est a dire comme si chaque appel a write(2) etait suivi d'un appel a fdatasync(2)). Consultez NOTES ci-dessous. O_EXCL S'assurer que cet appel cree le fichier : si cet attribut est specifie en conjonction avec O_CREAT et si le fichier pathname existe deja, open() echouera avec l'erreur EEXIST. Lorsque ces deux attributs sont specifies, les liens symboliques ne sont pas suivis : si pathname est un lien symbolique, open() echouera quel que soit l'endroit ou pointe le lien symbolique. En general, le comportement de O_EXCL est indetermine s'il est utilise sans O_CREAT. Il existe une exception toutefois : a partir de Linux 2.6, O_EXCL peut etre utilise sans O_CREAT si pathname fait reference a un peripherique bloc. Si le peripherique bloc est utilise par le systeme (par exemple, s'il est monte), open() echoue avec l'erreur EBUSY. Sur les systemes de fichiers NFS, O_EXCL n'est pris en charge qu'avec la version NFSv3 ou ulterieure, sur les noyaux 2.6 ou plus recents. Dans les environnements NFS ou la prise en charge d'O_EXCL n'est pas fournie, les programmes qui ont besoin de cette fonctionnalite pour verrouiller des taches risquent de rencontrer une concurrence critique (race condition). Les programmes portables qui veulent effectuer un verrouillage atomique de fichier en utilisant un fichier verrou et qui doivent eviter la dependance de la prise en charge NFS pour O_EXCL peuvent creer un fichier unique sur le meme systeme de fichiers (par exemple, avec le PID et le nom de l'hote), et utiliser link(2) pour creer un lien sur un fichier de verrouillage. Si link(2) renvoie 0, le verrouillage est reussi. Sinon, utiliser stat(2) sur ce fichier unique pour verifier si le nombre de liens a augmente jusqu'a 2, auquel cas le verrouillage est egalement reussi. O_LARGEFILE (LFS) Permettre d'ouvrir des fichiers dont la taille ne peut pas etre representee dans un off_t (mais peut l'etre dans un off64_t). La macro _LARGEFILE64_SOURCE doit etre definie (avant d'inclure tout fichier d'en-tete) pour obtenir cette definition. Definir la macro _FILE_OFFSET_BITS a 64 est la methode a favoriser pour acceder a des grands fichiers sur des systemes 32 bits, plutot que d'utiliser O_LARGEFILE (consultez feature_test_macros(7)). O_NOATIME (depuis Linux 2.6.8) Ne pas mettre a jour la date de dernier acces au fichier ((st_atime dans l'inoeud) quand le fichier est read(2). Cet attribut ne peut etre utilise que si l'une des conditions suivantes est vraie : - L'identifiant utilisateur effectif du fichier correspond a celui du proprietaire du fichier. - Le processus appelant a la capacite CAP_FOWNER dans son espace de noms utilisateur et l'identifiant utilisateur du proprietaire du fichier a une projection dans l'espace de noms. Cet attribut est seulement concu pour les programmes d'indexation et d'archivage, pour lesquels il peut reduire significativement l'activite du disque. L'attribut peut ne pas etre effectif sur tous les systemes de fichiers. Par exemple, avec NFS, l'heure d'acces est mise a jour par le serveur. O_NOCTTY Si pathname correspond a un peripherique de terminal -- consultez tty(4) --, il ne deviendra pas le terminal controlant le processus meme si celui-ci n'est attache a aucun autre terminal. O_NOFOLLOW Si le composant final (c'est-a-dire, celui obtenu par basename) de pathname est un lien symbolique, l'ouverture echoue avec l'erreur ELOOP. Les liens symboliques dans les composants apparus plus tot dans le chemin seront encore suivis (remarquez que l'erreur ELOOP qui peut intervenir dans ce cas ne peut pas etre distinguee de l'echec d'une ouverture a cause d'un trop grand nombre de liens symboliques lors de la resolution de composants dans le prefixe du chemin). Cet attribut est une extension FreeBSD qui a ete ajoutee dans Linux 2.1.126, puis normalisee dans POSIX.1-2008. Voir aussi O_PATH ci-dessous. O_NONBLOCK ou O_NDELAY Si possible, le fichier est ouvert en mode << non-bloquant >>. Ni la fonction open() ni aucune autre operation d'E/S ulterieure sur le descripteur de fichier renvoye ne laissera le processus appelant en attente. Remarquez que positionner cet attribut n'a pas d'effet sur une operation poll(2), select(2), epoll(7) et equivalentes, puisque ces interfaces informent simplement l'appelant si un descripteur de fichier est << ready >>, a savoir qu'une operation E/S effectuee sur le descripteur de fichier avec l'attribut O_NONBLOCK clear ne se bloquerait pas. Remarquez que cet attribut n'a aucun effet sur les fichiers ordinaires et les peripheriques de bloc ; c'est-a-dire que les operations d'E/S se bloqueront (brievement) lorsqu'une activite du peripherique est necessaire, independamment du positionnement de O_NONBLOCK. Comme la semantique de O_NONBLOCK pourrait eventuellement etre implementee, les applications ne doivent pas dependre d'un blocage comportemental quand elles indiquent cet attribut pour des fichiers ordinaires et des peripheriques de bloc. Pour la manipulation des FIFO (tubes nommes), voir egalement fifo(7). Pour une explication de l'effet de O_NONBLOCK en conjonction avec les verrouillages imperatifs et les baux de fichiers, voir fcntl(2). O_PATH (depuis Linux 2.6.39) Obtenir un descripteur de fichier qui peut etre utile de deux facons : pour indiquer la localisation dans l'arborescence du systeme de fichiers et pour effectuer des operations exclusivement au niveau du descripteur de fichier. Le fichier n'est pas lui-meme ouvert et d'autres operations sur le fichier (par exemple read(2), write(2), fchmod(2), fchown(2), fgetxattr(2), ioctl(2), mmap(2)) echoueront en renvoyant l'erreur EBADF. Les operations suivantes peuvent etre realisees sur le descripteur de fichier obtenu : - close(2). - fchdir(2), si le descripteur de fichier renvoie a un repertoire (depuis Linux 3.5). - fstat(2) (depuis Linux 3.6) - fstatfs(2) (depuis Linux 3.12) - Dupliquer le descripteur de fichier (dup(2), fcntl(2), F_DUPFD, etc.). - Consulter et affecter les valeurs des attributs du descripteur de fichier (fcntl(2), F_GETFD et F_SETFD). - Recuperer les attributs d'etat de fichiers ouverts au moyen de l'operation fcntl(2) F_GETFL : les attributs renvoyes comprendront le bit O_PATH. - Transmettre le descripteur de fichier comme l'argument dirfd de openat(2) et les autres appels systeme << *at() >>. Cela comprend linkat(2) avec AT_EMPTY_PATH (ou via procfs au moyen de AT_SYMLINK_FOLLOW) meme si le fichier n'est pas un repertoire. - Transmettre le descripteur de fichier a un autre processus a l'aide d'un socket de domaine UNIX (consultez SCM_RIGHTS dans unix(7)). Lorsque O_PATH est precise dans flags, seuls les bits O_CLOEXEC, O_DIRECTORY et O_NOFOLLOW de l'attribut sont pris en compte. L'ouverture d'un fichier ou d'un repertoire avec l'attribut O_PATH ne necessite pas de droits sur l'objet lui-meme (mais elle exige le droit d'execution sur les repertoires du prefixe de chemin). En fonction des operations ulterieures, la verification des droits du fichier adequats peut se faire (par exemple fchdir(2) exige le droit d'execution sur le repertoire auquel renvoie son argument de descripteur de fichier). Inversement, l'obtention de la reference a un objet de systeme de fichiers en l'ouvrant par l'attribut O_RDONLY exige que l'appelant ait le droit de lire l'objet meme quand l'operation ulterieure (par exemple, fchdir(2), fstat(2)) n'a pas besoin des droits de lecture sur l'objet. Si pathname est un lien symbolique et si l'attribut O_NOFOLLOW est precise, alors l'appel renvoie le descripteur de fichier d'un lien symbolique. Ce descripteur de fichier peut etre utilise comme l'argument dirfd lors d'appels aux fonctions fchownat(2), fstatat(2), linkat(2) et readlinkat(2) avec un chemin d'acces vide pour permettre a l'appel de s'executer sur le lien symbolique. Si pathname renvoie a un point de montage automatique non encore effectue, donc aucun autre systeme de fichiers n'y est monte, alors l'appel renvoie un descripteur de fichier qui se rapporte au repertoire de montage automatique sans effectuer de montage. fstatfs(2) peut alors etre utilise pour determiner s'il s'agit bien d'un point de montage automatique non non effectue (.f_type == AUTOFS_SUPER_MAGIC). Une utilisation de O_PATH sur des fichiers ordinaires consiste a fournir l'equivalent de la fonctionnalite O_EXEC de POSIX.1. Cela nous permet d'ouvrir un fichier sur lequel on a le droit d'execution mais pas de lecture, puis d'executer ce fichier selon des etapes comme suit : char buf[PATH_MAX]; fd = open("un_programme", O_PATH); snprintf(buf, PATH_MAX, "/proc/self/fd/%d", fd); execl(buf, "un_programme", (char *) NULL); Un descripteur de fichier O_PATH peut egalement etre fourni comme argument de fexecve(3). O_SYNC Les operations d'ecriture dans le fichier se derouleront selon les conditions d'execution des operations E/S synchrones avec garantie d'integrite du fichier (contrairement a l'execution des operations E/S synchrones avec garantie d'integrite des donnees fournie par O_DSYNC.) Au moment ou write(2) (ou un appel similaire) renvoie une donnee, cette donnee et les metadonnees associees au fichier ont ete transmises au materiel sur lequel s'execute l'appel (autrement dit, comme si chaque appel a write(2) etait suivi d'un appel a fsync(2)). Consultez NOTES ci-dessous. O_TMPFILE (depuis Linux 3.11) Creer un fichier temporaire sans nom. L'argument pathname indique un repertoire ; un inoeud sans nom sera cree dans le systeme de fichiers de ce repertoire. Tout ce qui est ecrit dans le fichier resultant sera perdu quand le dernier descripteur de fichier sera ferme, a moins de donner un nom au fichier. O_TMPFILE doit etre indique avec soit O_RDWR, soit O_WRONLY, et facultativement O_EXCL. Si O_EXCL n'est pas indique, alors linkat(2) peut etre utilise pour lier le fichier temporaire dans le systeme de fichiers, le rendant permanent, en utilisant du code comme : char path[PATH_MAX]; fd = open("/path/to/dir", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); /* E/S du fichier sur 'fd'... */ linkat(fd, "", AT_FDCWD, "/path/for/file", AT_EMPTY_PATH); /* Si l'appelant n'a pas la capacite CAP_DAC_READ_SEARCH (necessaire pour utiliser AT_EMPTY_PATH avec linkat(2)) et s'il existe un systeme de fichiers proc(5) monte, l'appel linkat(2) ci-dessus peut etre remplace par : snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd); linkat(AT_FDCWD, path, AT_FDCWD, "/path/for/file", AT_SYMLINK_FOLLOW); */ Dans ce cas, l'argument mode d'open() determine le mode de droits du fichier, comme avec O_CREAT. Indiquer O_EXCL en conjonction avec O_TMPFILE empeche de lier un fichier temporaire dans le systeme de fichiers comme precedemment (remarquez que la signification de O_EXCL dans ce cas est differente de la signification habituelle de O_EXCL). Les deux principaux cas d'utilisation de O_TMPFILE sont presentes ci-dessous : - Ameliorer la fonctionnalite tmpfile(3) : creation de fichiers temporaires sans situation de competition qui (1) sont automatiquement supprimes a la fermeture ; (2) ne peuvent jamais etre atteints par n'importe quel chemin ; (3) ne sont pas exposes aux attaques de lien symbolique ; et (4) ne necessitent pas a l'appelant d'inventer des noms uniques. - Creer un fichier initialement invisible, qui est ensuite peuple de donnees et ajuste aux attributs de systeme de fichiers adequats (fchown(2), fchmod(2), fsetxattr(2), etc.) avant d'etre lie de facon atomique dans le systeme de fichiers dans un etat completement forme (en utilisant linkat(2) comme decrit precedemment). O_TMPFILE necessite une prise en charge par le systeme de fichiers sous-jacent. Seule une partie des systemes de fichiers Linux fournit cette prise en charge. Dans l'implementation initiale, la prise en charge etait assuree pour les systemes de fichiers ext2, ext3, ext4, UDF, Minix et tmpfs. La prise en charge d'autres systemes de fichiers a ensuite ete ajoutee ainsi : XFS (Linux 3.15) ; Btrfs (Linux 3.16) ; F2FS (Linux 3.16) ; et ubifs (Linux 4.9) O_TRUNC Si le fichier existe, est un fichier ordinaire et que le mode d'acces permet l'ecriture (O_RDWR ou O_WRONLY), il sera tronque a une longueur nulle. Si le fichier est une FIFO ou un peripherique terminal, l'attribut O_TRUNC est ignore. Sinon, le comportement de O_TRUNC n'est pas precise. creat() L'appel creat() est equivalent a open() avec l'attribut flags egal a O_CREAT|O_WRONLY|O_TRUNC. openat() L'appel systeme openat() fonctionne de la meme facon que open(), les differences etant decrites ici. L'argument dirfd est utilise avec l'argument pathname comme suit : - Si le chemin donne dans pathname est absolu, dirfd est ignore. - Si le chemin fourni dans pathname est un chemin relatif et si dirfd a la valeur speciale AT_FDCWD, alors pathname est interprete par rapport au repertoire courant du processus appelant, comme dans open(). - Si pathname est un chemin relatif, il est interprete par rapport au repertoire reference par le descripteur de fichier dirfd (plutot que par rapport au repertoire courant du processus appelant, comme cela est fait par open() pour un chemin relatif). Dans ce cas, dirfd doit etre un repertoire qui a ete ouvert en lecture (O_RDONLY) ou en utilisant l'attribut O_PATH. Si le chemin fourni dans pathname est un chemin relatif et si dirfd n'est pas un descripteur de fichier valable, il en resulte une erreur (EBADF). (Specifier un numero de descripteur de fichier non valable dans dirfd peut etre utilise comme moyen de s'assurer que pathname est absolu.) openat2(2) L'appel systeme openat2(2) est une extension de openat() et il fournit un ensemble supplementaire aux fonctionnalites de openat(). Il est documente a part dans openat2(2). VALEUR RENVOYEE open(), openat() et creat() renvoient le nouveau descripteur de fichier (un entier non negatif) s'ils reussissent. En cas d'erreur, ou -1 est renvoye et errno est defini pour indiquer l'erreur. ERREURS open(), openat() et creat() peuvent echouer avec les erreurs suivantes : EACCES L'acces demande au fichier est interdit, ou la permission de parcours pour l'un des repertoires du chemin pathname est refusee, ou le fichier n'existe pas encore et le repertoire parent ne permet pas l'ecriture. (Consultez aussi path_resolution(7).) EACCES Lorsque O_CREAT est indique, le systcl protected_fifos ou protected_regular est active, le fichier existe deja ou est une FIFO ou un fichier ordinaire, le proprietaire du fichier n'est ni l'utilisateur actuel, ni celui du repertoire qui le contient, et ce repertoire est accessible en ecriture et en execution pour tout le monde. Pour plus de details, consultez les descriptions de /proc/sys/fs/protected_fifos et de /proc/sys/fs/protected_regular dans proc(5). EBADF (openat()) pathname est relatif mais dirfd n'est ni AT_FDCWD ni un descripteur de fichier valable. EBUSY O_EXCL etait indique dans flags et pathname se rapporte a un peripherique bloc utilise par le systeme (par exemple, il est monte). EDQUOT Si O_CREAT est indique, le fichier n'existe pas et le quota de blocs de disque ou d'inoeuds de l'utilisateur sur le systeme de fichiers a ete atteint. EEXIST pathname existe deja et O_CREAT et O_EXCL ont ete indiques. EFAULT nom_chemin pointe en dehors de l'espace d'adressage accessible. EFBIG Consultez EOVERFLOW. EINTR Pendant qu'il etait bloque en attente de l'ouverture d'un peripherique lent (par exemple, une FIFO ; consultez fifo(7)), l'appel a ete interrompu par un gestionnaire de signal ; consultez signal(7). EINVAL Le systeme de fichiers ne gere pas l'attribut O_DIRECT. Consultez NOTES pour de plus amples renseignements. EINVAL Valeur incorrecte dans flags. EINVAL O_TMPFILE a ete indique dans flags, mais ni O_WRONLY ni O_RDWR n'ont ete indiques. EINVAL O_CREAT etait indique dans flags et le composant final (<< basename >>) du pathname du nouveau fichier n'est pas valable (il contient par exemple des caracteres non autorises par le systeme de fichiers sous-jacent). EINVAL Le composant final (<< basename >>) de pathname n'est pas valable (il contient, par exemple, des caracteres non autorises par le systeme de fichiers sous-jacent). EISDIR Une ecriture a ete demandee alors que pathname correspond a un repertoire (en fait, O_WRONLY ou O_RDWR ont ete declares). EISDIR pathname fait reference a un repertoire existant, O_TMPFILE et soit O_WRONLY, soit O_RDWR, ont ete indiques dans flags, mais cette version du noyau ne fournit pas la fonctionnalite O_TMPFILE. ELOOP Trop de liens symboliques ont ete rencontres en parcourant nom_chemin. ELOOP pathname etait un lien symbolique, et flags indiquait O_NOFOLLOW mais pas O_PATH. EMFILE La limite par processus du nombre de descripteurs de fichiers ouverts a ete atteinte (voir la description de RLIMIT_NOFILE dans getrlimit(2)). ENAMETOOLONG nom_chemin est trop long. ENFILE La limite du nombre total de fichiers ouverts pour le systeme entier a ete atteinte. ENODEV pathname correspond a un fichier special et il n'y a pas de peripherique correspondant. (Ceci est un bogue du noyau Linux ; dans cette situation, ENXIO devrait etre renvoye.) ENOENT O_CREAT n'est pas positionne et le fichier nomme n'existe pas. ENOENT Un des repertoires du chemin d'acces nom_chemin n'existe pas ou est un lien symbolique pointant nulle part. ENOENT pathname fait reference a un repertoire inexistant, O_TMPFILE et soit O_WRONLY, soit O_RDWR, ont ete indiques dans flags, mais cette version du noyau ne fournit pas la fonctionnalite O_TMPFILE. ENOMEM Le fichier nomme est une FIFO, mais la memoire du tampon de la FIFO ne peut pas etre allouee car la limite dure par processus d'allocation de memoire pour des tubes (pipes) a ete atteinte et l'appelant n'est pas privilegie ; voir pipe(7). ENOMEM La memoire disponible du noyau n'etait pas suffisante. ENOSPC pathname devrait etre cree mais le peripherique concerne n'a plus assez de place pour un nouveau fichier. ENOTDIR Un element du chemin d'acces utilise comme repertoire dans pathname ne l'est pas, ou l'attribut O_DIRECTORY est utilise et pathname n'est pas un repertoire. ENOTDIR (openat()) pathname est un chemin relatif et le descripteur de fichier dirfd est associe a un fichier, pas a un repertoire. ENXIO O_NONBLOCK | O_WRONLY est positionne, le fichier nomme est une FIFO et le processus n'a pas cette FIFO ouverte en lecture. ENXIO Le fichier est un fichier special de peripherique et il n'existe aucun peripherique correspondant. ENXIO Le fichier est un socket de domaine UNIX. EOPNOTSUPP Le systeme de fichiers contenant pathname ne prend pas en charge O_TMPFILE. EOVERFLOW pathname fait reference a un fichier ordinaire qui est trop grand pour etre ouvert. Cela arrive quand une application compilee sur une plate-forme 32 bits sans -D_FILE_OFFSET_BITS=64 essaie d'ouvrir un fichier dont la taille depasse (2^31)-1 octets ; consultez egalement O_LARGEFILE ci-dessus. C'est l'erreur specifiee par POSIX.1 ; avant Linux 2.6.24, Linux fournissait l'erreur EFBIG dans ce cas. EPERM L'attribut O_NOATIME est indique, mais l'UID effectif de l'appelant n'est pas celui du proprietaire du fichier, et l'appelant n'est pas privilegie. EPERM La lecture a ete interrompue par un signal ; consultez fnctl(2). EROFS Un acces en ecriture est demande alors que pathname reside sur un systeme de fichiers en lecture seule. ETXTBSY Une ecriture a ete demandee alors que pathname correspond a un fichier executable actuellement utilise. ETXTBSY pathname se rapporte a un fichier actuellement utilise comme fichier d'echange et l'attribut O_TRUNC a ete indique. ETXTBSY pathname se rapporte a un fichier actuellement lu par le noyau (par exemple pour charger un module ou du micro-code), et un acces en ecriture a ete demande. EWOULDBLOCK L'attribut O_NONBLOCK est indique, et un bail incompatible est detenu sur le fichier (consultez fcntl(2)). VERSIONS L'effet (indefini) de O_RDONLY | O_TRUNC varie selon l'implementation. Sur de nombreux systemes, le fichier est effectivement tronque. E/S synchrones L'option POSIX-1.2008 << E/S synchrones >> decrit des variantes des E/S synchrones, ainsi que plusieurs attributs de open() permettant d'en controler le comportement : O_SYNC, O_DSYNC et O_RSYNC. Sans chercher a savoir si une implementation accepte cette option, elle doit au moins prendre en charge l'utilisation de O_SYNC pour les fichiers normaux. Linux met en oeuvre O_SYNC et O_DSYNC, mais pas O_RSYNC. De facon plus ou moins correcte, la glibc definit O_RSYNC de facon a avoir la meme valeur que O_SYNC. (O_RSYNC est defini dans le fichier d'en-tete du noyau Linux de HP PA-RISC, mais il n'est pas utilise). O_SYNC fournit l'execution d'E/S synchrones avec garantie d'integrite des fichiers, ce qui signifie que les operations d'ecriture envoient les donnees et les metadonnees associees au materiel. O_DSYNC fournit l'execution d'E/S synchrones avec garantie d'integrite des donnees, ce qui signifie que les operations d'ecriture envoient les donnees et les metadonnees associees au materiel, mais en envoyant seulement les mises a jour des metadonnees qui permettent d'assurer le bon deroulement d'une operation de lecture ulterieure. L'execution avec garantie d'integrite des donnees peut reduire le nombre d'acces au disque demandes par une application qui ne necessite pas l'execution avec garantie d'integrite des fichiers. Pour comprendre la difference entre ces deux types d'execution, imaginez deux extraits de metadonnees d'un fichier : l'horodatage de la derniere modification (st_mtime) et la longueur du fichier. Toutes les operations d'ecriture modifieront l'horodatage de la derniere modification, mais seules les ecritures en fin de fichier modifieront la longueur. L'horodatage de derniere modification n'est pas necessaire pour garantir une lecture correcte du fichier, contrairement a la longueur. Ainsi, O_DSYNC transmettrait seulement la metadonnee relative a la longueur du fichier (quand O_SYNC y ajouterait l'horodatage de derniere modification). Avant Linux 2.6.33, Linux mettait seulement en oeuvre l'attribut O_SYNC de open(). Cependant, lorsque cet attribut etait indique, la plupart des systemes de fichiers fournissait des fonctionnalites equivalentes a l'execution des E/S synchrones avec garantie de l'integrite des donnees (autrement dit, O_SYNC etait de fait mis en oeuvre comme O_DSYNC). A partir de Linux 2.6.33, une veritable prise de charge de O_SYNC est fournie. Cependant, pour assurer la compatibilite ascendante binaire, O_DSYNC a ete defini avec la meme valeur que le O_SYNC << historique >>, et O_SYNC a ete defini comme un nouvel attribut (de deux bits) qui comprend l'attribut O_DSYNC. Ceci permet d'assurer que les applications compilees avec les nouveaux en-tetes auront au moins la semantique de O_DSYNC avant Linux 2.6.33. Differences entre bibliotheque C et noyau Depuis la glibc 2.26, la fonction enveloppe de la glibc de open() utilise l'appel systeme openat() au lieu de l'appel systeme open() du noyau. Pour certaines architectures, cela est aussi vrai avant la glibc 2.26. STANDARDS open() creat() openat() POSIX.1-2008. openat2(2) Linux. Les attributs O_DIRECT, O_NOATIME, O_PATH et O_TMPFILE sont specifiques a Linux. _GNU_SOURCE doit etre definie pour obtenir leurs definitions. Les attributs O_CLOEXEC, O_DIRECTORY et O_NOFOLLOW ne sont pas specifies dans POSIX.1-2001, mais le sont dans POSIX.1-2008. Depuis glibc 2.12, leurs definitions peuvent etre obtenues en definissant soit _POSIX_C_SOURCE avec une valeur superieure ou egale a 200809L, soit _XOPEN_SOURCE avec une valeur superieure ou egale a 700. Dans glibc 2.11 et les versions precedentes, les definitions peuvent etre obtenues en definissant _GNU_SOURCE. HISTORIQUE open() creat() SVr4, 4.3BSD, POSIX.1-2001. openat() POSIX.1-2008. Linux 2.6.16, glibc 2.4. NOTES Sous Linux, l'attribut O_NONBLOCK est parfois utilise pour indiquer qu'on veut ouvrir mais pas necessairement dans l'intention de lire ou d'ecrire. Il est typiquement utilise pour ouvrir des peripheriques dans le but de recuperer un descripteur de fichier pour l'utiliser avec ioctl(2). Notez que open() peut ouvrir des fichiers speciaux mais creat() ne peut pas en creer, il faut utiliser mknod(2) a la place. Si un fichier est cree, ses horodatages st_atime, st_ctime, st_mtime (respectivement heure de dernier acces, de derniere modification d'etat, et de derniere modification ; consultez stat(2)) sont definis a l'heure actuelle, ainsi que les champs st_ctime et st_mtime du repertoire parent. Sinon, si le fichier est modifie a cause de l'attribut O_TRUNC, ses champs st_ctime et st_mtime sont remplis avec l'heure actuelle. Les fichiers du repertoire /proc/pid/fd affichent les descripteurs de fichier ouverts du processus ayant l'identifiant pid. Les fichiers du repertoire /proc/pid/fdinfo presentent encore plus d'informations sur ces descripteurs de fichier. Voir proc(5) pour plus de details sur ces deux repertoires. Le fichier d'en-tete du noyau Linux ne definit pas O_ASYNC ; son synonyme FASYNC (derive de BSD) l'est en revanche. Description de fichier ouvert Le terme << description de fichier ouvert >> correspond a la terminologie POSIX pour faire reference a des entrees dans la table des fichiers ouverts du systeme. Dans d'autres contextes, cet objet est egalement appele << objet de fichier ouvert >>, << gestionnaire de fichier >>, << entree de la table des fichiers ouverts >> ou encore, dans le jargon des developpeurs du noyau, struct file. Lorsqu'un descripteur de fichiers est duplique (au moyen de dup(2) ou d'un equivalent), la copie fait reference a la meme description de fichier ouvert que le descripteur de fichier d'origine. Les deux descripteurs de fichier partagent donc la meme position dans le fichier et les memes attributs d'etat. Un tel partage peut egalement se produire entre deux processus : un processus enfant cree au moyen de fork(2) herite des copies des descripteurs de fichier de ses parents, et ces copies pointent vers les memes descriptions de fichier ouvert. Chaque operation open(2) sur un fichier cree une nouvelle description de fichier ouvert ; ainsi, il peut y avoir plusieurs descriptions de fichier ouvert correspondant a un inoeud de fichier. Sur Linux, on peut utiliser KCMP_FILE de kcmp(2) pour tester si deux descripteurs de fichier (dans le meme processus ou dans deux processus differents) se rapportent a la meme description de fichier ouvert. NFS Plusieurs problemes se posent avec le protocole NFS, concernant entre autres O_SYNC, et O_NDELAY. Sur les systemes de fichiers NFS, ou la correspondance d'UID est activee, open() peut renvoyer un descripteur de fichier alors qu'une requete read(2) par exemple sera refusee avec le code d'erreur EACCES. En effet, le client a effectue open() en verifiant les autorisations d'acces, mais la correspondance d'UID est calculee par le serveur au moment des requetes de lecture ou d'ecriture. FIFO Ouvrir les blocs de fin de FIFO en lecture et ecriture jusqu'a ce que l'autre fin soit egalement ouverte (par un autre processus ou un autre thread). Voir fifo(7) pour plus de details. Mode d'acces au fichier Contrairement aux autres valeurs qui peuvent etre indiquees dans flags, les valeurs du mode d'acces O_RDONLY, O_WRONLY et O_RDWR ne sont pas des bits individuels. Ils definissent l'ordre des deux bits de poids faible de flags, et ont pour valeur respective 0, 1 et 2. En d'autres termes, l'association O_RDONLY | O_WRONLY est une erreur logique et n'a certainement pas la meme signification que O_RDWR. Linux reserve le sens suivant au mode 3 d'acces special et non standard (en binaire, 11) de l'attribut : verification des droits en lecture et ecriture du fichier, et renvoi d'un descripteur qui ne peut etre utilise ni en lecture, ni en ecriture. Ce mode d'acces non standard est utilise par certains pilotes Linux afin de renvoyer un descripteur qui n'est destine qu'a des operations ioctl(2) propres aux peripheriques. Justification des appels openat() et des API des descripteurs de fichier de repertoires openat() et les autres appels systeme similaires, ainsi que les fonctions de bibliotheques qui recoivent pour argument un descripteur de fichier de repertoire (c'est-a-dire, execveat(2), faccessat(2), fanotify_mark(2), fchmodat(2), fchownat(2), fspick(2), fstatat(2), futimesat(2), linkat(2), mkdirat(2), mknodat(2), mount_setattr(2), move_mount(2), name_to_handle_at(2), open_tree(2), openat2(2), readlinkat(2), renameat(2), renameat2(2), statx(2), symlinkat(2), unlinkat(2), utimensat(2), mkfifoat(3) et scandirat(3)) gerent deux problemes avec les anciennes interfaces. L'explication est ici donnee dans le contexte de l'appel openat(), mais elle est semblable pour les autres interfaces. Tout d'abord, openat() permet a une application d'eviter les problemes d'acces concurrents lors de l'utilisation de open() pour ouvrir des fichiers dans des repertoires autres que le repertoire courant. Ces problemes sont dus au fait que l'un des composants du chemin donne a open() peut etre modifie parallelement a l'appel open(). Supposons par exemple qu'on veuille creer le fichier dir1/dir2/xxx.dep alors que le fichier dir1/dir2/xxx existe. Le probleme est qu'entre la verification de son existence et l'etape de creation du fichier, dir1 ou dir2 (qui pourraient etre des liens symboliques) pourraient etre modifies pour pointer vers un autre endroit. De tels problemes peuvent etre evites en ouvrant un descripteur de fichier sur le repertoire cible, puis en fournissant ce descripteur comme argument dirfd de (disons) fstatat(2) et openat(). L'utilisation du descripteur de fichier dirfd a egalement d'autres avantages : - le descripteur de fichier est une reference stable au repertoire, meme si le repertoire est renomme ; - le descripteur de fichier ouvert empeche le systeme de fichiers sous-jacent d'etre demonte quand un processus detient un repertoire en cours de fonctionnement sur le systeme de fichiers. Enfin, openat() permet d'implementer un << repertoire courant >> par thread, grace a des descripteurs de fichier maintenus par l'application. Cette fonctionnalite peut egalement etre obtenue en jouant avec /proc/self/fd/dirfd, mais de facon moins efficace. L'argument dirfd de ces API peut etre obtenu par l'utilisation de open() ou de openat() pour ouvrir un repertoire (avec le drapeau O_RDONLY ou O_PATH). Sinon, un tel descripteur de fichier peut etre obtenu en appliquant un dirfd(3) au flux d'un repertoire cree avec opendir(3). Quand on donne aux API un argument dirfd de AT_FDCWD ou qu'un chemin indique est absolu, ils gerent leur argument de chemin de la meme maniere que les API conventionnelles correspondantes. Toutefois dans ce cas, plusieurs API ont un argument flags qui offre un acces a cette fonctionnalite non disponible avec les interfaces conventionnelles correspondantes. O_DIRECT L'attribut O_DIRECT peut imposer des restrictions d'alignement pour la longueur et l'adresse des tampons de l'espace utilisateur et des decalages de fichier pour les entrees-sorties. Sous Linux, les restrictions d'alignement varient en fonction du systeme de fichiers et de la version du noyau, et il peut aussi ne pas y en avoir. La manipulation des entrees-sorties O_DIRECT mal alignees varie aussi ; elles peuvent soit echouer avec l'erreur EINVAL soit se replier sur des entrees-sorties mises en tampon. Depuis Linux 6.1, la prise en charge de O_DIRECT et les restrictions d'alignement pour un fichier peuvent etre recherchees avec statx(2) en utilisant l'attribut STATX_DIOALIGN. La prise en charge de STATX_DIOALIGN varie selon le systeme de fichiers ; consultez statx(2). Certains systemes de fichiers fournissent leur propre interface pour rechercher les restrictions d'alignement de O_DIRECT, par exemple l'operation XFS_IOC_DIOINFO de xfsctl(3). STATX_DIOALIGN devrait etre utilise a la place quand il est disponible. Si aucun de ces interfaces n'est disponible, alors la prise en charge directe des entrees-sorties et les restrictions d'alignement peuvent uniquement etre presumees a partir des caracteristiques connues du systeme de fichiers, du fichier individuel, des peripheriques de stockage sous-jacents et de la version du noyau. Dans Linux 2.4, la plupart des systemes de fichiers bases sur des peripheriques bloc requierent que l'adresse du fichier et la longueur et l'adresse memoire de tous les segments d'entrees-sorties soient des multiples de la taille de bloc du systeme de fichiers (habituellement 4096 octets). Dans Linux 2.6.0, cela a ete assoupli a la taille du bloc logique du peripherique bloc (habituellement 512 octets). La taille de bloc logique d'un peripherique bloc peut etre determinee avec l'operation BLKSSZGET de ioctl(2) ou avec la commande shell suivante : blockdev --getss Les E/S O_DIRECT ne devraient jamais etre executees en meme temps que l'appel systeme fork(2), si le tampon memoire est une projection privee (c'est-a-dire n'importe quelle projection en memoire creee avec l'attribut MAP_PRIVATE de mmap(2), y compris la memoire allouee sur le tas et les tampons alloues de facon statique). Toutes ces E/S, qu'elles soient soumises par l'intermediaire d'une interface d'E/S asynchrone ou depuis un autre thread du processus, devraient etre achevees avant l'appel de fork(2). En cas d'echec, les consequences pourraient etre une corruption de memoire ou un comportement imprevisible dans les processus pere et fils. Cette restriction ne s'applique pas quand le tampon memoire pour les E/S O_DIRECT a ete cree en utilisant shmat(2) ou mmap(2) avec l'attribut MAP_SHARED. Cette restriction ne s'applique pas non plus quand le tampon memoire a ete configure comme MADV_DONTFORK avec madvise(2), en s'assurant qu'il ne sera pas disponible au fils apres fork(2). L'attribut O_DIRECT a ete introduit par SGI IRIX, qui a des restrictions d'alignement identiques a Linux 2.4. IRIX a aussi un appel fcntl(2) pour obtenir les alignements et tailles appropries. FreeBSD 4.x a introduit un attribut du meme nom, mais sans les restrictions d'alignement. La gestion de O_DIRECT a ete ajoutee dans Linux 2.4.10. Les noyaux Linux plus anciens ignorent simplement cet attribut. Certains systemes de fichiers peuvent ne pas gerer cet attribut et open() echouera avec l'erreur EINVAL s'il est utilise. Les applications devraient eviter de melanger des entrees-sorties O_DIRECT et normales pour le meme fichier, en particulier sur des regions d'un meme fichier qui se recouvrent. Meme si le systeme de fichiers gere les problemes de coherence dans cette situation, le debit global d'entrees-sorties sera moindre que si un seul mode etait utilise. De la meme facon, les applications devraient eviter de melanger l'utilisation de mmap(2) et d'entrees-sorties directes pour les memes fichiers. Le comportement de O_DIRECT avec NFS differe des systemes de fichiers locaux. Les anciens noyaux, ou les noyaux configures d'une certaine facon, peuvent ne pas gerer cette combinaison. Le protocole NFS ne gere pas le passage de l'attribut au serveur, les entrees-sorties O_DIRECT ne font donc que le cache des pages du client ; le serveur pourra toujours utiliser un cache pour les entrees-sorties. Le client demande au serveur de rendre les entrees-sorties synchrones pour preserver la semantique synchrone de O_DIRECT. Certains serveurs fonctionnent mal dans ces circonstances, tout particulierement si les entrees-sorties sont de petite taille. Certains serveurs peuvent aussi etre configures pour mentir aux clients et indiquer que les entrees-sorties ont atteint un espace de stockage stable ; ceci evitera la perte de performance en augmentant les risques pour l'integrite des donnees en cas de probleme d'alimentation du serveur. Le client NFS Linux n'a pas de restriction d'alignement pour les entrees-sorties O_DIRECT. En resume, O_DIRECT est un outil potentiellement puissant qui doit etre utilise avec precaution. Les applications devraient utiliser O_DIRECT comme une option pour ameliorer les performances et qui est desactivee par defaut. BOGUES Actuellement, il n'est pas possible d'activer les entrees-sorties controlees par les signaux en indiquant O_ASYNC lors de l'appel open() ; il faut utiliser fcntl(2) pour activer cet attribut. Deux codes d'erreur differents - EISDIR et ENOENT -- doivent etre verifies pour essayer de determiner si le noyau prend en charge la fonctionnalite O_TMPFILE. Quand O_CREAT et O_DIRECTORY sont indiques dans flags et que le fichier indique par pathname n'existe pas, open() creera un fichier ordinaire (c'est-a-dire que O_DIRECTORY est ignore). VOIR AUSSI chmod(2), chown(2), close(2), dup(2), fcntl(2), link(2), lseek(2), mknod(2), mmap(2), mount(2), open_by_handle_at(2), openat2(2), read(2), socket(2), stat(2), umask(2), unlink(2), write(2), fopen(3), acl(5), fifo(7), inode(7), path_resolution(7), symlink(7) TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot , Frederic Hantrais , Jean- Philippe MENGUAL et Jean-Pierre Giraud Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 16 janvier 2024 open(2)