Описание тега rabat
Linux предоставляет два механизма для мониторинга событий файловой системы; подсистема dnotify
и с inotify
.
Старший из двух, подсистема dnotify
, был введен в ядре версии 2.4.0. Это позволяет приложениям зарегистрируйтесь, чтобы получать уведомления об изменениях в каталоге, через вызов fcntl()
интерфейса. Сами уведомления доставляются через сигналы. В подсистема dnotify
механизма ограничивается мониторингом изменений в каталоге, это не позволяет контролировать отдельные файлы. Кроме того, это требует сохраняя дескриптор открытого файла в каталог под наблюдением. В подсистема dnotify
механизм был устаревшим в 2.6.13, когда его
вводили.
Новые программы должны использовать его
механизм, который поддерживает мониторинг папок и отдельных файлов. Это, однако, не основана на сигналах. С помощью inotify
экземпляр связывается с файлового дескриптора. Уведомления о событиях могут быть считаны из этого дескриптора файла.
Ограничение обоих механизмов является то, что нет возможности посмотреть каталоги рекурсивно. Это означает, что мониторинг должен быть установлен отдельно для каждого каталога поддерева, которое должно находиться под наблюдением.
Пример (подсистема dnotify
):
#определите _gnu_source
#включить <флагов.ч>
#включить <сигнал.ч>
#включить заголовочный файл <stdio.ч>
#включить <запустите.ч>
/* Для обработки ошибок */
#включить <stdlib.ч>
код #include <errno значение.ч>
#включить <ошибки.ч>
статические летучих инт event_fd;
статический недействительным обработчик(инт сиг, siginfo_t в *Си, ничтоже *сведения)
{
event_fd = Си->обработчик был;
}
тап_п(АГДС, типа char *переменной argv[])
{
в sigaction структуры СА;
инт ФД;
если(argc < 2)
ошибка(EXIT_FAILURE, 0, "отсутствует аргумент");
СА.sa_sigaction = обработчик;
не удалось(&СА.в sa_mask);
СА.в Flag = sa_siginfo и;
в sigaction(SIGRTMIN + 1, &СА, значение null);
если((fд = открыть(из argv[1], флагов o_rdonly)) < 0)
ошибка(EXIT_FAILURE, ошибка, "не удалось открыть" %S "и" аргумент argv[1]);
если параметры(fcntl(FD, то на выполнении f_setsig значение SIGRTMIN + 1) < 0)
ошибка(EXIT_FAILURE, ошибка, "не удалось установить подсистема dnotify сигнал");
если параметры(fcntl(FD, то запретить, DN_MODIFY|DN_CREATE|DN_DELETE|DN_MULTISHOT))
ошибка(EXIT_FAILURE, ошибки,
"не удалось зарегистрировать уведомление для "%S"", и argv[1]);
в то время как (1) {
пауза();
функции printf("событие произошло на ФД=%д\п", event_fd);
}
}
Объяснение:
вызов fcntl(ФД выполнении f_setsig значение SIGRTMIN + 1)
Задает сигнал посылается, когда происходят события уведомления. Нулевое значение указывает, что сигналы sigio
(по умолчанию) будет отправлено. Любое другое значение, включая сигналы sigio
, это интерпретируется как сигнал к отправке, а не. В последнем случае сигнал обработчик получает siginfo_t в
структуру в качестве своего второго аргумента, и обработчик был
полевой структуры будет содержать дескриптор файла, который сгенерировал событие.
Если в реальном времени сигнал (>= SIGRTMIN
) используется для уведомлений, несколько ввода/вывода событий могут быть очереди, используя один и тот же сигнал количество (в зависимости от доступной памяти). В реальном времени сигнал должен быть использован, особенно при использовании DN_MULTISHOT
.
вызов fcntl(FD, то запретить, DN_MODIFY|DN_CREATE|DN_DELETE|DN_MULTISHOT)
Задает события, которые вызывают уведомления, когда каталог, на который указывает fd, или любые содержащиеся в нем файлы будут изменены. Доступны следующие типы событий:
DN_ACCESS
обращении к файлу.DN_MODIFY
файл изменен.DN_CREATE
файл создается.DN_DELETE
файл отсоединяется.DN_RENAME
файл переименовывается в каталоге.DN_ATTRIB
атрибутов файла меняется.
Уведомления, как правило, один выстрел, т. е. приложения должны перерегистрироваться для получения дальнейшего уведомления. Если DN_MULTISHOT
указанного уведомления остаются в силе, пока не будет явно удален.
Пример (с inotify
):
#включить заголовочный файл <stdio.ч>
#включить <stdlib.ч>
код #include <sys в/с inotify.ч>
/* Для PATH_MAX */
#Включить <ограничения.ч>
/* Для обработки ошибок */
код #include <errno значение.ч>
#включить <ошибки.ч>
тап_п(АГДС, типа char *переменной argv[]) {
инт ФД, БВ, Лен, я;
Чара баф[размер(структуру struct inotify_event) + PATH_MAX];
если (argc < 2)
ошибка(EXIT_FAILURE, 0, "отсутствует аргумент");
если ((fд = inotify_init, но()) < 0)
ошибка(EXIT_FAILURE, ошибка, "не удалось инициализировать экземпляр inotify");
Для (я = 1; я < АГДС; я++) {
если ((БВ = вызов inotify_add_watch (ФД, агду[я],
IN_MODIFY И | IN_CREATE | IN_DELETE)) < 0)
ошибка(EXIT_FAILURE, ошибки,
"не удалось добавить помощью inotify часы для "%S"", и argv[я]);
}
пока ((длн = читать(ФД, баф, оператор sizeof(баф))) > 0) {
я = 0;
а (я < лен) {
структуру struct inotify_event *т. е. = (структуры struct inotify_event*) &buf с[я];
функции printf("событие произошло для "%S": "аргумент argv[т. е.->программы WD]);
если (Т. Е.->Маска & in_modify и)
функции printf("%s был изменен\п", т. е.->лен ? т. е.->название файла:"");
остальное, если (Т. Е.->Маска & IN_CREATE)
функции printf("%s был создан\н", т. е.->наименование);
остальное, если (Т. Е.->Маска & IN_DELETE)
функции printf("%s был удален\н", т. е.->наименование);
еще
функции printf("неожиданное событие\Н");
я += оператор sizeof(структуры struct inotify_event) + т. е.->лен;
}
}
ошибка(EXIT_FAILURE, лен == 0 ? 0 : ошибка, "не удалось прочитать события inotify");
}
Объяснение:
ФД = inotify_init, но()
Инициализирует новый его
экземпляр. Возвращаемое значение является дескриптор файла, связанный с только что созданным с inotify
события очереди. По умолчанию дескриптор файла блокирует.
компания WD = вызов inotify_add_watch (ФД, агду[я], in_modify и | IN_CREATE | IN_DELETE)
Новые элементы в список часы.к.а. часы добавлены с вызов inotify_add_watch()
. Третий аргумент-это битовая маска, используемая для указания в inotify
события, чтобы наблюдать за. Доступны следующие типы событий:
In_access и
доступе к файлу.In_attrib и
атрибуты файла не изменился.In_close_write и
файл открыт для записи закрыт.IN_CLOSE_NOWRITE
файл открыт только для чтения закрыт.IN_CREATE
файл или каталог создается в пределах наблюдаемой директории.IN_DELETE
файл или каталог удален в пределах наблюдаемой директории.IN_DELETE_SELF
файла или каталога посмотрел удаляется.In_modify и
файл был изменен.IN_MOVE_SELF
файла или каталога посмотрел перемещается.Событием
файл перемещен из наблюдаемой директории.И in_moved_to
файл перемещается в наблюдаемой директории.In_open и
файл открывается.IN_ALL_EVENT
все вышеперечисленное.. Также событие in_move
эквиваленти in_moved_to|событием
IN_CLOSE
эквивалентноin_close_write и|IN_CLOSE_NOWRITE
Следующие параметры могут быть установлены в маске аргумент выполнении inotify_add_watch()
:
IN_DONT_FOLLOW
не следовать символическим ссылкам.IN_EXCL_UNLINK
не генерируют события несвязанные файлы, которые будут использоваться в наблюдаемой директории.IN_MASK_ADD
добавить следили за событиями последовательно, если смотреть уже существует.In_oneshot в
автоматически снять часы после одного события из него.IN_ONLYDIR
только смотреть Pathname, если это каталог.
Значение, возвращаемое при выполнении inotify_add_watch()
часы дескриптор, связанный с файловой системы объект наблюдают в его
инстанции указал на ФД
. Если указанный объект уже смотрел, дескриптор существующего часы возвращается.
пока ((длн = читать(ФД, баф, оператор sizeof(баф))) > 0) {
я = 0;
а (я < лен) {
структуру struct inotify_event *т. е. = (структуры struct inotify_event*) &buf с[я];
/* ... */
я += оператор sizeof(структуры struct inotify_event) + т. е.->лен;
}
}
Каждый успешный прочитать()
из файла дескриптора, связанного с его
экземпляр возвращает один или более inotify_event
структуры со следующими полями.
инт компания WD
смотреть дескриптор запущенного смотреть.uint32_t маска
Маска из событий, которые вызвали часы.uint32_t печенья
уникальное печенье связывания соответствующих событий.uint32_t лен
размер имени Поля.тип char имя[]
необязательные null-завершенной имя файла, который вызвал событие в наблюдаемом каталоге.
Помимо биты, соответствующие типы событий передают вызов inotify_add_watch()
, маска поле может иметь следующие состояния биты:
IN_IGNORED
часы были удалены (черезinotify_rm_watch()
, путь несвязанные и т. д.).IN_ISDIR
событие, инициированное каталог.IN_Q_OVERFLOW
случае, если очередь переполнена. Кроме того, компания WD имеет значение -1.IN_UNMOUNT
файловой системы, содержащий смотрел путь был демонтирован.
Длина каждой inotify_event
структура с размером sizeof(inotify_event) + лен
из-за переменной длины имени
Поля.
До ядра версии 2.6.21, если переданный буфер для чтения()
является слишком маленьким, чтобы провести следующее мероприятие, то read() возвращает 0. Начиная с 2.6.21, прочитать()
не удается, и значение errno
устанавливается в значение einval
.