Linux программирование в примерах
Некоторые системы System V разрешают пользователям передавать свои файлы. (При смене владельца соответствующие биты файлов
иsetuidсбрасываются.) Это может быть особенной проблемой, когда файлы извлекаются из архиваsetgidили.tar; извлеченные файлы имеют UID и GID, закодированный в архиве. На таких системах программы.cpioиtarимеют опции, предотвращающие это, но важно знать, что поведениеcpioдействительно отличается на разных системах.chown()В разделе 6.3 «Имена пользователя и группы» мы увидим, как соотносить имена пользователя и группы с соответствующими числовыми значениями
5.5.2. Изменение прав доступа:
иchmod()fchmod()Изменение прав доступа осуществляется с помощью одного из двух системных вызовов,
иchmod():fchmod()#include <sys/types.h> /* POSIX */#include <sys/stat.h>int chmod(const char *path, mode_t mode);int fchmod(int fildes, mode_t mode);работает с аргументом имени файла, achmod()работает с открытым файлом. (В POSIX нет вызоваfchmod(), поскольку система игнорирует установки прав доступа для символических ссылок. Хотя на некоторых системах такой вызов действительно есть). Как и для большинства других системных вызовов, они возвращают 0 в случае успеха и -1 при ошибке. Права доступа к файлу может изменить лишь владелец файла илиlchmod().rootЗначение mode создается таким же образом, как для
иopen(), как обсуждалось в разделе 4.6 «Создание файлов». См. также табл. 5.2, в которой перечислены константы прав доступа.creat()Система не допустит установки бита setgid (
), если группа файла не совпадает с ID действующей группы процесса или с одной из его дополнительных групп. (Мы пока не обсуждали подробно эти проблемы; см. раздел 11.1.1 «Реальные и действующие ID».) Разумеется, эта проверка не относится кS_ISGIDили коду, выполняющемуся какroot.root5.5.3. Изменение временных отметок:
utime()Структура
содержит три поля типаstruct stat:time_tВремя последнего доступа к файлу (чтение)st_atimeВремя последнего изменения файла (запись).st_mtimeВремя последнего изменения индекса файла (например, переименования)st_ctimeЗначение
представляет время в «секундах с начала эпохи». Эпоха является Началом Времени для компьютерных систем GNU/Linux и Unix используют в качестве начала Эпохи полночь 1 января 1970 г по универсальному скоординированному времени (UTC). [62] Системы Microsoft Windows используют в качестве начала Эпохи полночь 1 января 1980 г. (очевидно, местное время).time_tЗначения
иногда называют временными отметками (timestamps). В разделе 6.1 «Время и даты» мы рассмотрим, как получаются эти данные и как они используются. Пока достаточно знать, чем является значениеtime_tи то, что оно представляет секунды с начала Эпохи.time_tСистемный вызов
позволяет изменять отметки времени доступа к файлу и его изменения:utime()#include <sys/types.h> /* POSIX */#include <utime.h>int utime(const char *filename, struct utimbuf *buf);Структура
выглядит следующим образом:utimbufstruct 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 лет. Некто, набрав '
', что отображает время доступа (вместо времени изменения по умолчанию), увидел бы, что последний раз данный файл просматривали 10 лет назад. Поэтому программа архивации должна сохранить оригинальные значения времени доступа и изменения, прочесть файл для архивации, а затем восстановить первоначальное время с помощьюls -lu.utime()Аналогичным образом, рассмотрите случай архивирующей программы, восстанавливающей файл из архива. В архиве хранятся первоначальные значения времени доступа и изменения. Однако, когда файл извлечен из архива во вновь созданную копию на диске, новый файл имеет текущие дату и время для значений времени доступа и изменения.
Однако полезнее, когда вновь созданный файл выглядит, как если бы он имел тот же возраст, что и оригинальный файл в архиве. Поэтому архиватор должен иметь возможность устанавливать значения времени доступа и изменения в соответствии со значениями в архиве.