UTIMENSAT(2) Manuel du programmeur Linux UTIMENSAT(2)

utimensat, futimens - Modifier les horodatages d'un fichier avec une précision d'une nanoseconde

#include <fcntl.h> /* Définition des constantes AT_* */
#include <sys/stat.h>
int utimensat(int dirfd, const char *pathname,
              const struct timespec times[2], int flags);
int futimens(int fd, const struct timespec times[2]);
Exigences de macros de test de fonctionnalités pour la glibc (consulter feature_test_macros(7)) :

utimensat():

Depuis la glibc 2.10 :
_POSIX_C_SOURCE >= 200809L
Avant la glibc 2.10 :
_ATFILE_SOURCE

futimens():

Depuis la glibc 2.10 :
_POSIX_C_SOURCE >= 200809L
Avant la glibc 2.10 :
_GNU_SOURCE

utimensat() et futimens() mettent à jour les horodatages d'un fichier avec une précision d'une nanoseconde. Ceci change de l'appel historique ou de utimes(2), qui permettent seulement une précision d'une seconde et d'une microseconde respectivement pour l'établissement des horodatages de fichier.

Avec utimensat(), le fichier est indiqué à l'aide du chemin fournit dans pathname. Avec futimens(), le fichier dont les horodatages doit être mis à jour est indiqué par un descripteur de fichier ouvert, fd.

For both calls, the new file timestamps are specified in the array times: times[0] specifies the new "last access time" (atime); times[1] specifies the new "last modification time" (mtime). Each of the elements of times specifies a time as the number of seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). This information is conveyed in a structure of the following form:


struct timespec {
    time_t tv_sec;        /* secondes     */
    long   tv_nsec;       /* nanosecondes */
};

L'horodatage mis à jour pour le fichier est configuré à la valeur la plus importante gérée par le système de fichiers et qui n'est pas supérieure à l'horodatage fourni

Si le champ tv_nsec d'une des structures timespec prend la valeur particulière UTIME_NOW, alors l'horodatage correspondant du fichier est défini à l'heure actuelle. Si le champ tv_nsec d'une des structures timespec prend la valeur particulière UTIME_OMIT, alors l'horodatage correspondant du fichier reste inchangé. Dans ces deux cas, la valeur du champ tv_sec est ignoré.

Si times est NULL, les deux horodatages sont définis à l'heure actuelle.

Pour définir les deux horodatages à l'heure actuelle (c'est-à-dire quand times vaut NULL ou que les deux champs tv_nsec valent UTIME_NOW), il faut :
1.
soit que l'utilisateur ait les droits d'écriture sur le fichier ;
2.
soit que l'identifiant effectif de l'appelant corresponde au propriétaire du fichier ;
3.
ou que le processus appelant ait les privilèges nécessaires.

Pour pouvoir effectuer d'autres changements que de définir les horodatage à l'heure actuelle (c'est-à-dire quand times n'est pas NULL et que ni le champ tv_nsec ne vaut UTIME_NOW ni le champ tv_nsec ne vaut UTIME_OMIT), les conditions 2 ou 3 ci-dessus s'appliquent.

Si les deux champs tv_nsec valent UTIME_OMIT, aucune vérification n'est effectuée sur le propriétaire ou les permissions et les horodatages ne sont pas modifiés, mais les autres situations d'erreur sont toujours détectées.

Si le chemin donné dans pathname est relatif, il est par défaut interprété par rapport au répertoire référencé par le descripteur de fichier ouvert dirfd (plutôt que par rapport au répertoire courant du processus, comme pour utimes(2) pour les chemins relatifs). Consultez openat(2) pour avoir les raisons pour lesquelles ceci peut être utile.

Si pathname est un chemin relatif, et si dirfd a la valeur spéciale AT_FDCWD, alors pathname est interprété par rapport au répertoire courant du processus appelant, comme dans utimes(2).

Si pathname est absolu, alors dirfd est ignoré.

Le champ flags est un champ de bits qui peut être nul ou inclure les constantes suivantes, définies dans <fcntl.h> :

AT_SYMLINK_NOFOLLOW
Si pathname indique un lien symbolique, alors mettre à jour l'horodatage du lien, plutôt que le fichier pointé.

S'ils réussissent les appels utimensat() et futimens() renvoient zéro, sinon ils renvoient -1 et remplissent errno avec le code d'erreur.

EACCES
times is NULL, or both tv_nsec values are UTIME_NOW, and the effective user ID of the caller does not match the owner of the file, the caller does not have write access to the file, and the caller is not privileged (Linux: does not have either the CAP_FOWNER or the CAP_DAC_OVERRIDE capability).
EBADF
(futimens()) fd n'est pas un descripteur de fichier valable.
EBADF
(utimensat()) pathname est un chemin relatif, mais dirfd n'est ni AT_FDCWD ni un descripteur de fichier valable.
EFAULT
times pointe vers une adresse incorrecte ; ou dirfd valait AT_FDCWD et pathname est NULL ou une adresse incorrecte.
EINVAL
Valeur incorrecte dans flags.
EINVAL
Valeur incorrecte dans un des champs tv_nsec (valeur en dehors de l'intervalle allant de 0 à 999.999.999 et ne valant ni UTIME_NOW ni UTIME_OMIT) ; ou une valeur incorrecte dans un des champs tv_sec.
EINVAL
pathname est NULL, dirfd ne vaut pas AT_FDCWD et flags contient AT_SYMLINK_NOFOLLOW.
ELOOP
(utimensat()) Trop de liens symboliques ont été rencontrés en parcourant pathname.
ENAMETOOLONG
(utimensat()) pathname est trop long.
ENOENT
(utimensat()) Un élément du chemin d'accès pathname ne correspond pas un répertoire ou àun fichier existant ou pathname est une chaîne vide.
ENOTDIR
(utimensat()) pathname est un chemin relatif, mais dirfd n'est ni AT_FDCWD ni un descripteur de fichier correspondant à un répertoire ; ou l'un des composants au début de pathname n'est pas un répertoire.
EPERM
The caller attempted to change one or both timestamps to a value other than the current time, or to change one of the timestamps to the current time while leaving the other timestamp unchanged, (i.e., times is not NULL, neither tv_nsec field is UTIME_NOW, and neither tv_nsec field is UTIME_OMIT) and either:
  • l'identifiant d'utilisateur effectif de l'appelant ne correspond pas au propriétaire du fichier et l'appelant n'est pas privilégié (Linux : n'a pas la capacité CAP_FOWNER).
  • le fichier est marqué comme n'acceptant que des ajouts ou est immuable (voir chattr(1)).
EROFS
Le fichier se trouve sur un système de fichiers en lecture seule.
ESRCH
(utimensat()) Un élément au début du chemin d'accès pathname ne permet pas le parcours.

utimensat() a été ajouté à Linux dans le noyau 2.6.22 ; la glibc le gère depuis la version 2.6.

La prise en charge de futimens() est apparu dans la glibc 2.6.

Pour une explication des termes utilisés dans cette section, consulter attributes(7).
Interface Attribut Valeur
utimensat(), futimens() Sécurité des threads MT-Safe

futimens() et utimensat() sont spécifiés dans POSIX.1-2008.

utimensat() rend futimesat(2) obsolète.

Sous Linux, les horodatages ne peuvent pas être modifiés pour un fichier marqué comme étant immuable, et la seule modification autorisée pour les fichier n'autorisant que des ajouts est de définir les horodatages à l'heure actuelle. (C'est cohérent avec le comportement historique de utime(2) et de utimes(2) sous Linux)

If both tv_nsec fields are specified as UTIME_OMIT, then the Linux implementation of utimensat() succeeds even if the file referred to by dirfd and pathname does not exist.

Sous Linux, futimens() est une fonction de bibliothèque implémentée à l'aide de l'appel système utimensat(). Pour ceci, l'appel système utimensat() de Linux implémente une fonctionnalité non standard : si pathname est NULL, alors l'appel modifie les horodatages du fichier correspondant au descripteur de fichier dirfd (qui peut correspondre à n'importe quel type de fichier). En utilisant cette fonctionnalité, l'appel futimens(fd, times) est implémenté comme ceci :


utimensat(fd, NULL, times, 0);

Note, however, that the glibc wrapper for utimensat() disallows passing NULL as the value for pathname: the wrapper function returns the error EINVAL in this case.

Plusieurs bogues affectent utimensat() et futimens() sur les noyaux antérieurs à 2.6.26. Ces bogues sont soit des non conformités avec le brouillon de la spécification POSIX.1 soit des incohérences avec le comportement historique de Linux.
  • POSIX.1 spécifie que si un des champs tv_nsec prend la valeur UTIME_NOW ou UTIME_OMIT, alors la valeur du champs tv_sec correspondant doit être ignorée. À la place, la valeur du champ tv_sec doit être nul (ou une erreur EINVAL sera produite).
  • Ces bogues indiquent que pour ce qui est de la vérification des droits, le cas où les deux champs tv_nsec ne valent pas UTIME_NOW n'est pas toujours traité de la même façon que lorsque times est NULL, et le cas où une des valeurs tv_nsec vaut UTIME_NOW et l'autre vaut UTIME_OMIT n'est pas traité de la même façon que quand times pointe vers un tableau de structures contenant des valeurs de temps arbitraires. De ce fait, il se peut que : a) des horodatages de fichier puissent être mis à jour par un processus qui ne devrait pas avoir le droit de faire ces mises à jour ; b) des horodatages de fichier ne puissent pas être mis à jour par un processus qui devrait avoir le droit de faire ces mises à jour ; et c) la mauvaise valeur d'errno puisse être renvoyée en cas d'erreur.
  • POSIX.1 indique qu'un processus qui a les droits d'accès en écriture pour un fichier peut faire un appel avec times valant NULL ou avec times pointant vers un tableau de structures dans lesquelles les deux champs tv_nsec valent UTIME_NOW pour mettre à jour les deux horodatages à l'heure actuelle. Cependant, futimens() vérifie à la place si le mode d'accès du descripteur de fichier permet l'écriture.

chattr(1), touch(1), futimesat(2), openat(2), stat(2), utimes(2), futimes(3), inode(7), path_resolution(7), symlink(7)

Cette page fait partie de la publication 5.10 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

La traduction française de cette page de manuel a été créée par Christophe Blaess https://www.blaess.fr/christophe/, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org> et David Prévot <david@tilapin.org>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.

9 juin 2020 Linux