- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Linux программирование в примерах - Арнольд Роббинс
Шрифт:
Интервал:
Закладка:
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 г. (очевидно, местное время).
Значения 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 «Возвращаясь к переносимости».
Замещающая функция находится в файле lib/utime.c в дистрибутиве Coreutils Следующий код является версией из Coreutils 5.0. Номера строк относятся к началу файла:
24 #include <sys/types.h>
25
26 #ifdef HAVE_UTIME_H
27 # include <utime.h>
28 #endif
39
30 #include "full-write.h"
31 #include "safe-read.h"
32
33 /* Некоторые системы (даже имеющие <utime.h>) нигде не объявляют
34 эту структуру. */
35 #ifndef HAVE_STRUCT_UTIMBUF
36 struct utimbuf
37 {
38 long actime;
39 long modtime;
40 };
41 #endif
42
43 /* Эмулировать utime(file, NULL) для систем (подобных 4.3BSD),
44 которые не устанавливают в этом случае текущее время для времени
45 доступа и изменения file. Вернуть 0, если успешно, -1 если нет. */
46
47 static int
48 utime_null(const char *file)
49 {
50 #if HAVE_UTIMES_NULL
51 return utimes(file, 0);
52 #else
53 int fd;
54 char c;
55 int status = 0;
56 struct stat sb;
57
58 fd = open(file, O_RDWR);
59 if (fd < 0
60 || fstat(fd, &sb) < 0
61 || safe_read(fd, &c, sizeof c) == SAFE_READ_ERROR
62 || lseek(fd, (off_t)0, SEEK_SET) < 0
63 || full_write(fd, &c, sizeof c) != sizeof с
64 /* Можно сделать - это необходимо на SunOS4.1.3 с некоторой комбинацией
65 заплат, но та система не использует этот код: у нее есть utimes.
66 || fsync(fd) < 0
67 */
68 || (st.st_size == 0 && ftruncate(fd, st.st_size) < 0)
69 || close(fd) < 0)
70 status = -1;
71 return status;
72 #endif
73 }
74
75 int
76 rpl_utime(const char *file, const struct utimbuf *times)
77 {
78 if (times)
79 return utime(file, times);
80
81 return utime_null(file);
82 }
Строки 33–41 определяют структуру struct utimbuf; как сказано в комментарии, некоторые системы не объявляют эту структуру. Работу осуществляет функция utime_null(). Используется системный вызов utimes(), если он доступен (utimes() является сходным, но более развитым системным вызовом, который рассматривается в разделе 14.3.2 «Файловое время в микросекундах: utimes().» Он допускает также в качестве второго аргумента NULL, что означает использование текущего времени.)
В случае, когда время должно обновляться вручную, код осуществляет обновление, прочитав сначала из файла байт, а затем записав его обратно. (Первоначальный touch Unix работал таким способом.) Операции следующие:
1. Открыть файл, строка 58.
2. Вызвать для файла stat(), строка 60.
3. Прочесть один байт, строка 61 Для наших целей safe_read() действует подобно read(); это объясняется в разделе 10.4.4 «Повторно запускаемые системные вызовы»).
4. Переместиться обратно на начало файла с помощью lseek(), строка 62. Это сделано для записи только что прочитанного байта обратно поверх себя.
5. Записать байт обратно, строка 63. full_write() действует подобно write(); это также рассматривается в разделе 10.4.4 «Повторно запускаемые системные вызовы»).
6. Если файл имеет нулевой размер, использовать ftruncate() для установки его размера в ноль (строка 68). Это не изменяет файл, но имеет побочный эффект обновления времени доступа и изменения (ftruncate() была описана в разделе 4 8 «Установка длины файла».)
7. Закрыть файл, строка 69.
Все эти шаги осуществляются в одной длинной последовательной цепи проверок внутри if. Проверки сделаны так, что если любое сравнение неверно, utime_null() возвращает -1, как обычный системный вызов, errno автоматически устанавливается системой для использования кодом более высокого уровня.
Функция rpl_utime() (строки 75–82) является «заместителем utime()». Если второй аргумент не равен NULL, она вызывает настоящую utime(). В противном случае она вызывает utime_null().
5.5.4. Использование fchown() и fchmod() для обеспечения безопасности

