18.7. Напишите программу, которая задействует функцию nftw() для обхода дерева каталога и выводит в результате количество и долю (в процентах) файлов различных типов (обычных, каталогов, символических ссылок и т. д.) в данном дереве.
18.8. Реализуйте функцию nftw(). (Для этого понадобятся, среди прочих, системные вызовы opendir(), readdir(), closedir() и stat().)
18.9. В разделе 18.10 показаны два различных метода (с применением функций fchdir() и chdir() соответственно), позволяющие вернуться в предыдущий рабочий каталог после изменения текущего. Предположим, мы выполняем такую операцию многократно. Как вы думаете, какой метод окажется более эффективным? Почему? Напишите программу для обоснования вашего ответа.
19. Мониторинг событий файлов
Некоторым приложениям требуется иметь возможность осуществлять мониторинг файлов или каталогов, чтобы определить, произошли ли с объектами наблюдения те или иные события. Например, графический менеджер файлов должен быть в состоянии установить, когда пользователь добавляет или удаляет файлы из отображаемого в настоящий момент каталога, фоновый процесс может также проводить мониторинг собственного файла конфигурации, чтобы определять, был ли изменен этот файл.
Начиная с версии ядра 2.6.13, Linux предоставляет механизм inotify, позволяющий приложениям осуществлять мониторинг событий файлов. В данной главе описывается его использование.
Механизм inotify призван заменить устаревший механизм dnotify, предоставлявший лишь часть возможностей inotify. В конце главы мы приводим краткое описание dnotify, концентрируясь при этом на преимуществах inotify.
Механизмы inotify и dnotify — специфичные механизмы Linux. (Ряд других операционных систем предоставляют схожие механизмы. Например, BSD реализован интерфейс API kqueue.)
Лишь в некоторых библиотеках реализованы интерфейсы API, по своим свойствам еще более абстрактные и портируемые, чем механизмы inotify и dnotify. Использование данных библиотек может быть предпочтительным для отдельных приложений. В части этих библиотек применяются механизмы inotify и dnotify, но только в тех системах, где указанные механизмы доступны. FAM (File Alteration Monitor (монитор изменения файлов) и Gamin — пример таких библиотек. См.: oss.sgi.com/projects/fam/.
Далее перечислены ключевые шаги использования API inotify.
1. Приложение задействует системный вызов inotify_init() для создания
2. Приложение информирует ядро о том, какие файлы ему необходимы, с помощью функции inotify_and_watch() для добавления элементов в список наблюдения объекта inotify, созданного в предыдущем шаге. Каждый элемент списка наблюдения состоит из путевого имени, а также битовой маски. Она определяет список событий, мониторинг которых необходимо осуществлять для данного имени. В результате выполнения функция inotify_and_watch() возвращает
3. Чтобы получить оповещения о событиях, приложение выполняет для дескриптора файла inotify операции чтения read(). Любая успешно выполненная операция возвращает одну или несколько структур inotify_event, каждая из которых содержит информацию о произошедшем событии, имеющем отношение к одному из наблюдаемых с помощью объекта inotify путевых имен.
4. По завершении мониторинга приложение закрывает дескриптор файла inotify. Это позволяет удалить все элементы списка наблюдения, связанные с объектом inotify.
Механизм inotify может использоваться для мониторинга файлов и каталогов. При мониторинге каталога приложение будет оповещено о событиях, касающихся только самого каталога, но не файлов, хранящихся в нем.
Механизм мониторинга inotify не является рекурсивным. Если приложению необходимо осуществлять мониторинг по всему поддереву каталога, оно должно произвести вызовы inotify_and_watch() для каждого каталога в дереве.
Мониторинг файлового дескриптора inotify может проходить с помощью интерфейсов select(), poll(), epoll и, начиная с версии Linux 2.6.25, ввода-вывода, управляемого сигналом. Если события доступны для чтения, то вышеприведенные интерфейсы обозначают файловый дескриптор inotify как читаемый. Для получения дополнительной информации об указанных интерфейсах см. главу 59.
Механизм inotify — это необязательный компонент ядра Linux, настраиваемый с помощью опций CONFIG_INOTIFY и CONFIG_INOTIFY_USER.
Системный вызов inotify_init() создает новый объект inotify.
#include
int inotify_init(void);
Возвращает файловый дескриптор или -1 при ошибке.