Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах
Шрифт:

Чтобы изменить только одну временную отметку, используйте оригинальное значение из

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

Поделиться:
Популярные книги

Законы Рода. Том 5

Flow Ascold
5. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 5

Идеальный мир для Социопата 4

Сапфир Олег
4. Социопат
Фантастика:
боевая фантастика
6.82
рейтинг книги
Идеальный мир для Социопата 4

Архонт

Прокофьев Роман Юрьевич
5. Стеллар
Фантастика:
боевая фантастика
рпг
7.80
рейтинг книги
Архонт

Идущий в тени. Книга 2

Амврелий Марк
2. Идущий в тени
Фантастика:
фэнтези
6.93
рейтинг книги
Идущий в тени. Книга 2

Мне нужна жена

Юнина Наталья
Любовные романы:
современные любовные романы
6.88
рейтинг книги
Мне нужна жена

Я же бать, или Как найти мать

Юнина Наталья
Любовные романы:
современные любовные романы
6.44
рейтинг книги
Я же бать, или Как найти мать

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Барон нарушает правила

Ренгач Евгений
3. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон нарушает правила

Столичный доктор. Том III

Вязовский Алексей
3. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том III

Ты не мой BOY

Рам Янка
5. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ты не мой BOY

Маршал Советского Союза. Трилогия

Ланцов Михаил Алексеевич
Маршал Советского Союза
Фантастика:
альтернативная история
8.37
рейтинг книги
Маршал Советского Союза. Трилогия

Авиатор: назад в СССР 12

Дорин Михаил
12. Покоряя небо
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Авиатор: назад в СССР 12

Крестоносец

Ланцов Михаил Алексеевич
7. Помещик
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Крестоносец

Муж на сдачу

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Муж на сдачу