Other Alias
utimensat
ОБЗОР
#include <fcntl.h> /* определения констант 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]);
Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):
utimensat():
Начиная с glibc 2.10: _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
До glibc 2.10: _ATFILE_SOURCE
futimens():
Начиная с glibc 2.10: _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
До glibc 2.10: _GNU_SOURCE
ОПИСАНИЕ
Вызовы utimensat() и futimens() обновляют временные метки файла с
наносекундной точностью. Этим они отличаются от utime(2) и utimes(2),
которые имеют секундную и микросекундную точность, соответственно.
В вызове utimensat() файл задаётся в pathname по имени. В вызове futimens() файл указывается в виде открытого файлового дескриптора в fd.
У обоих вызовов новые временные метки файла указываются в массиве times: в times[0] задаётся новое «время последнего доступа» (atime); в times[1] задаётся новое «время последнего изменения» (mtime). В каждом элементе times указывается время в виде количества секунд и наносекунд, прошедших с начала эпохи (1970-01-01 00:00:00 +0000 (UTC)). Эта информация представляет собой структуру следующего формата:
struct timespec { time_t tv_sec; /* секунды */ long tv_nsec; /* наносекунды */ };
Обновлённые временные метки файла устанавливаются в самое большое значение, поддерживаемое файловой системой, но не больше чем указанное время.
Если в поле tv_nsec одной из структур timespec указано специальное значение UTIME_NOW, то соответствующая временная метка файла устанавливается в значение текущего времени. Если в поле tv_nsec одной из структур timespec указано специальное значение UTIME_OMIT, то соответствующая временная метка файла не изменяется. В обоих случаях значение поля tv_sec игнорируется.
Если значение times равно NULL, то значение обеих временных меток становится равным текущему времени.
Права доступа
Чтобы установить временные метки файла равными текущему времени (т.е., значение times равно NULL, или оба значения поля tv_nsec равно UTIME_NOW) требуется одно из:1. вызывающий должен иметь право на запись в файл;
2. эффективный пользовательский идентификатор вызывающего должен совпадать с идентификатором владельца файла;
3. вызывающий должен иметь соответствующие права.
Чтобы установить временные метки файла равными не текущему времени (т. е., значение times не равно NULL, или оба значения поля tv_nsec не равны UTIME_NOW или UTIME_OMIT) требуется выполнение условия 2 или 3.
Если в обоих значениях поле tv_nsec равно UTIME_OMIT, то проверки владения файлом и права доступа к нему не выполняются, и временные метки файла не изменяются, но всё равно могут проверяться другие условия возникновения ошибок.
Особенности utimensat()
Если в pathname указано относительное значение имени, то по умолчанию оно отсчитывается от каталога, на который ссылается открытый файловый дескриптор, dirfd (а не от текущего рабочего каталога вызывающего процесса, как это делается в utimes(2) для относительных имён). В openat(2) объяснено почему это может быть полезно.Если в pathname задан относительный путь и dirfd равно специальному значению AT_FDCWD, то pathname рассматривается относительно текущего рабочего каталога вызывающего процесса (как utimes(2)).
Если в pathname задан абсолютный путь, то dirfd игнорируется.
Значение поля flags представляет собой битовую маску и может равняться 0 или содержать следующую константу (определена в <fcntl.h>):
AT_SYMLINK_NOFOLLOW Если pathname указывает на символьную ссылку, то обновляются временные метки ссылки, а не файла, на который она ссылается.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении utimensat() и futimens() возвращается 0. При
ошибке возвращается -1, а в errno содержится код ошибки.
ОШИБКИ
EACCES Значение times равно NULL, или в обоих значениях поле tv_nsec равно UTIME_NOW и:
EBADF (futimens()) Значение fd не является правильным файловым дескриптором.
EBADF (utimensat()) В pathname содержится относительный путь, но значение dirfd не равно AT_FDCWD и не является правильным файловым дескриптором.
EFAULT Значение times указывает на некорректный адрес; или dirfd равно AT_FDCWD и pathname равно NULL или содержит некорректный адрес.
EINVAL Некорректное значение flags.
EINVAL Некорректное значение в одном из полей tv_nsec (значение вне диапазона от 0 до 999999999 и не равно UTIME_NOW или UTIME_OMIT) или некорректное значение в одном из полей tv_sec.
EINVAL Значение pathname равно NULL, dirfd не равно AT_FDCWD и flags содержит AT_SYMLINK_NOFOLLOW.
ELOOP (utimensat()) Во время определения pathname встретилось слишком много символьных ссылок.
ENAMETOOLONG (utimensat()) Слишком длинное значение аргумента pathname.
ENOENT (utimensat()) Компонент пути pathname не ссылается на существующий каталог или файл, или в pathname указана пустая строка.
ENOTDIR (utimensat()) В pathname содержится относительный путь, но значение dirfd не равно AT_FDCWD или не является файловым дескриптором, ссылающимся на каталог; или один из компонентов pathname не является каталогом.
EPERM Вызывающий пытается изменить одну или обе временные метки на значение, отличное от текущего времени, или изменить одну из временных меток на текущее время, а другую оставить неизменной (т. е., значение times не равно NULL, у обоих значений поле tv_nsec не равно UTIME_NOW, и у обоих значений поле tv_nsec не равно UTIME_OMIT) и:
EROFS Файл расположен в файловой системе, доступной только для чтения.
ESRCH (utimensat()) В одном из каталогов префикса pathname не разрешён поиск.
ВЕРСИИ
Вызов utimensat() был добавлен в ядро Linux версии 2.6.22; поддержка в glibc доступна с версии 2.6.Поддержка futimens() появилась в glibc 2.6.
АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс Атрибут Значение
utimensat(),
futimens()
безвредность в потоках: безвредно (MT-Safe)
СООТВЕТСТВИЕ СТАНДАРТАМ
Вызовы futimens() и utimensat() определены в POSIX.1-2008.
ЗАМЕЧАНИЯ
Вызов utimensat() заменяет устаревший futimesat(2).
В Linux, временные метки нельзя изменять у файлов, помеченных как неизменяемые (immutable), а у файлов, помеченных как только для добавления, можно изменить метку только на значение текущего времени (это соответствует сложившемуся исторически поведению в Linux вызовов utime(2) и utimes(2)).
В Linux, futimens() представляет собой библиотечную функцию на основе системного вызова utimensat(). Для этого в Linux-версии системного вызова utimensat() реализовано нестандартное свойство: если значение pathname равно NULL, то вызов изменяет временные метки файла на который ссылается файловый дескриптор dirfd (который может указывать на файл любого типа). С помощью этого свойства вызов futimens(fd, times) реализован как:
utimensat(fd, NULL, times, 0);
Если оба поля tv_nsec равны UTIME_OMIT, то вызов utimensat() реализации Linux завершается без ошибки, даже, если файл, на который ссылается dirfd и pathname, не существует.