Для функции lutimes() файл указывается через путь, с тем отличием от utimes(), что если данный путь оказывается символической ссылкой, то она не разыменовывается; вместо этого меняются метки времени самой ссылки.

Функция futimes() поддерживается, начиная с версии 2.3 библиотеки glibc, функция lutimes() — начиная с версии 2.6.

15.2.2. Изменение меток времени файла с помощью системного вызова utimensat() и функции futimens()

Системный вызов utimensat() (поддерживается, начиная с версии ядра 2.6.22) и библиотечная функция futimens() (поддерживается с версии glibc 2.6) позволяют в расширенном диапазоне задавать метки времени последнего доступа к файлу или времени его последнего изменения. К числу преимуществ данных интерфейсов относятся следующие.

• Можно задавать метки времени с наносекундной точностью. Это лучше микросекундной точности, которая обеспечивается системным вызовом utimes().

• Есть возможность независимого задания меток времени (то есть по одной). Как было показано ранее, для изменения только одной метки времени с помощью старых интерфейсов необходимо сначала выполнить системный вызов stat(), чтобы извлечь значение другой метки времени, а затем указать извлеченное значение вместе с меткой времени, чье значение следует изменить. (Это может привести к состоянию соперничества, если какой-либо другой процесс выполнил операцию, которая обновила метку времени, вклинившись между этими двумя шагами.)

• Можно независимо указывать для любой метки времени значение текущего времени. Чтобы изменить текущее время только для одной метки с помощью старых интерфейсов, необходимо задействовать системный вызов stat() для извлечения информации о метке времени, значение которой следует оставить без изменений, а также функцию gettimeofday() для получения текущего времени.

Эти интерфейсы не описаны в стандарте SUSv3, но включены в стандарт SUSv4.

Системный вызов utimensat() обновляет метки времени файла, указанного в аргументе pathname, присваивая им значения, передаваемые в массиве times.

#define _XOPEN_SOURCE 700 /* Или define _POSIX_C_SOURCE >= 200809 */

#include

int utimensat(int dirfd, const char *pathname,

const struct timespec times[2], int flags);

Возвращает 0 при успешном завершении и –1 при ошибке

Если для аргумента times указано значение NULL, обе метки времени файла обновляются, принимая значение текущего времени. Если аргумент times не равен NULL, то новая метка времени последнего доступа указывается в элементе times[0], а новая метка времени последнего изменения — в элементе times[1]. Каждый элемент массива times является структурой следующего вида:

struct timespec {

time_t tv_sec; /* Секунды ('time_t' является целочисленным типом) */

long tv_nsec; /* Наносекунды */

};

Поля в этой структуре указывают время в секундах и наносекундах, прошедших прошедших с начала «эры UNIX» (см. раздел 10.1).

Чтобы задать для одной метки времени текущее время, следует передать специальное значение UTIME_NOW в соответствующее поле tv_nsec. Если же нужно оставить одну из меток времени без изменений, то специальное значение UTIME_OMIT требуется передать в соответствующее поле tv_nsec. В обоих случаях игнорируется значение в соответствующем поле tv_sec.

В качестве аргумента dirfd можно либо передать значение AT_FDCWD, и тогда аргумент pathname будет интерпретирован так же, как и для системного вызова utimes(), либо передать файловый дескриптор, указывающий на каталог. Назначение второго варианта описано в разделе 18.11.

Аргумент flags может быть равен либо 0, либо AT_SYMLINK_NOFOLLOW. Последнее означает, что аргумент pathname не следует разыменовывать, если он является символической ссылкой (то есть метки времени самой символической ссылки не следует менять). В противоположность этому системный вызов utimes() всегда разыменовывает символические ссылки.

В приведенном ниже фрагменте кода для времени последнего доступа устанавливается значение текущего времени, а время последнего изменения остается без изменений:

struct timespec times[2];

times[0].tv_sec = 0;

times[0].tv_nsec = UTIME_NOW;

times[1].tv_sec = 0;

times[1].tv_nsec = UTIME_OMIT;

if (utimensat(AT_FDCWD, "myfile", times, 0) == -1)

errExit("utimensat");

Права доступа при изменении меток времени с помощью системного вызова utimensat() (и функции futimens()) подобны тем, которые используются в старых API, и подробно описаны на странице utimensat(2) руководства.

Библиотечная функция futimens() обновляет метки времени файла, на который ссылается дескриптор открытого файла fd.

#include _GNU_SOURCE

#include

int futimens(int fd, const struct timespec times[2]);

Возвращает 0 при успешном завершении и –1 при ошибке

Аргумент times функции futimens() применяется так же, как и в системном вызове utimensat().

15.3. Принадлежность файла
Перейти на страницу:

Похожие книги