, поскольку система игнорирует установки прав доступа для символических ссылок. Хотя на некоторых системах такой вызов действительно есть). Как и для большинства других системных вызовов, они возвращают 0 в случае успеха и -1 при ошибке. Права доступа к файлу может изменить лишь владелец файла или
root
.
Значение mode
создается таким же образом, как для
open
и
creat
, как обсуждалось в разделе 4.6 «Создание файлов». См. также табл. 5.2, в которой перечислены константы прав доступа.
Система не допустит установки бита setgid (
S_ISGID
), если группа файла не совпадает с ID действующей группы процесса или с одной из его дополнительных групп. (Мы пока не обсуждали подробно эти проблемы; см. раздел 11.1.1 «Реальные и действующие ID».) Разумеется, эта проверка не относится к
root
или коду, выполняющемуся как
root
.
5.5.3. Изменение временных отметок:
utime
Структура
struct stat
содержит три поля типа
time_t
:
st_atime
Время последнего доступа к файлу (чтение)
st_mtime
Время последнего изменения файла (запись).
st_ctime
Время последнего изменения индекса файла (например, переименования)
Значение
time_t
представляет время в «секундах с начала эпохи». Эпоха является Началом Времени для компьютерных систем GNU/Linux и Unix используют в качестве начала Эпохи полночь 1 января 1970 г по универсальному скоординированному времени (UTC). [62] Системы Microsoft Windows используют в качестве начала Эпохи полночь 1 января 1980 г. (очевидно, местное время).
62
UTC представляет собой независимое от языка сокращение для Coordinated Universal Time (универсальное скоординированное время). Старый код (а иногда и люди постарше) называют это Гринвичским временем (Greenwich Mean Time, GMT), которое является временем в Гринвиче, Великобритания. Когда стали широко использоваться часовые пояса, в качестве точки отсчета, относительно которого все остальные часовые пояса отсчитывались либо вперед, либо назад, был выбран Гринвич — Примеч. автора.
Значения
time_t
иногда называют временными отметками (timestamps). В разделе 6.1 «Время и даты» мы рассмотрим, как получаются эти данные и как они используются. Пока достаточно знать, чем является значение
time_t
и то, что оно представляет секунды с начала Эпохи.
Системный вызов
utime
позволяет изменять отметки времени доступа к файлу и его изменения:
#include <sys/types.h> /* POSIX */
#include <utime.h>
int utime(const char *filename, struct utimbuf *buf);
Структура
utimbuf
выглядит следующим образом:
struct utimbuf {
time_t actime; /* время доступа */
time_t modtime; /* время изменения */
};
При успешном вызове возвращается 0, в противном случае
возвращается -1. Если
buf
равен
NULL
, система устанавливает время доступа и время изменения равным текущему времени.
Чтобы изменить только одну временную отметку, используйте оригинальное значение из
struct stat
. Например.
/* Для краткости проверка ошибок опущена */
struct stat sbuf;
struct utimbuf ut;
time_t now;
time(&now); /* Получить текущее время дня, см. след. главу */
stat("/some/file", &sbuf); /* Заполнить sbuf */
ut.actime = sbuf.st_atime; /* Время доступа без изменений */
ut.modtime = now - (24 * 60 * 60);
/* Установить modtime на 24 часа позже */
utime("/some/file", &ut); /* Установить значения */
Вы можете спросить себя: «Почему может понадобиться кому-нибудь изменять времена доступа и изменения файла?» Хороший вопрос.
Чтобы на него ответить, рассмотрите случай программы, создающей дублирующие архивы, такой, как
tar
или
cpio
. Эти программы должны прочесть содержание файла, чтобы заархивировать его. Чтение файла, конечно, изменяет время доступа к файлу.
Однако, этот файл, возможно, не читался человеком в течение 10 лет. Некто, набрав '
ls -lu
', что отображает время доступа (вместо времени изменения по умолчанию), увидел бы, что последний раз данный файл просматривали 10 лет назад. Поэтому программа архивации должна сохранить оригинальные значения времени доступа и изменения, прочесть файл для архивации, а затем восстановить первоначальное время с помощью
utime
.
Аналогичным образом, рассмотрите случай архивирующей программы, восстанавливающей файл из архива. В архиве хранятся первоначальные значения времени доступа и изменения. Однако, когда файл извлечен из архива во вновь созданную копию на диске, новый файл имеет текущие дату и время для значений времени доступа и изменения.
Однако полезнее, когда вновь созданный файл выглядит, как если бы он имел тот же возраст, что и оригинальный файл в архиве. Поэтому архиватор должен иметь возможность устанавливать значения времени доступа и изменения в соответствии со значениями в архиве.
ЗАМЕЧАНИЕ. В новом коде вы можете захотеть использовать вызов
utimes
(обратите внимание на s в имени), который описан далее в книге, в разделе 14.3.2 «Файловое время в микросекундах:
utimes
»
5.5.3.1. Подделка
utime(file, NULL)
Некоторые более старые системы не устанавливают значения времени доступа и изменения равным текущему времени, когда второй аргумент
utime
равен
NULL
. Однако код более высокого уровня (такой, как GNU
touch
) проще, если он может полагаться на один стандартизованный интерфейс.
Поэтому библиотека GNU Coreutils содержит замещающую функцию для
utime
, которая обрабатывает этот случай, которую потом может вызвать код более высокого уровня. Это отражает принцип проектирования «выбор лучшего интерфейса для работы», который мы описали в разделе 1.5 «Возвращаясь к переносимости».