18: if (f->level > maxDepth) return 0;
19: if (name && fnmatch(name, file + f->base, FNM_PERIOD)) return 0;
20:
21: if (flags == FTW_DNR) {
22: fprintf(stderr, "find: %s: недопустимые полномочия\n", file);
23: } else {
24: printf("%s\n", file);
25: }
26:
27: return 0;
28: }
29:
30: int main(int argc, const char ** argv) {
31: int flags = FTW_PHYS;
32: int i;
33: int problem = 0;
34: int tmp;
35: int rc;
36: char * chptr;
37:
38: /* поиск первого параметры командной строки (который должен
39: находиться после списка путей */
40: i = 1;
41: while (i < argc && *argv[i] != '-') i++;
42:
43: /* обработать опции командной строки */
44: while (i < argc && !problem) {
45: if (!strcmp(argv[i], "-name")) {
46: i++;
47: if (i == argc)
48: problem = 1;
49: else
50: name = argv[i++];
51: } else if (!strcmp(argv[i], "-depth")) {
52: i++;
53: flags |= FTW_DEPTH;
54: } else if (!strcmp (argv[i], "-mount") ||
55: !strcmp(argv[i], "-xdev")) {
56: i++;
57: flags |= FTW_MOUNT;
58: } else if (!strcmp (argv[i], "-mindepth") ||
59: !strcmp (argv[i], "-maxdepth")) {
60: i++;
61: if (i == argc)
62: problem = 1;
63: else {
64: tmp = strtoul(argv[i++], &chptr, 10);
65: if (*chptr)
66: problem = 1;
67: else if (!strcmp(argv[i - 2], "-mindepth"))
68: minDepth = tmp;
69: else
70: maxDepth = tmp;
71: }
72: }
73: }
74:
75: if (problem) {
76: fprintf(stderr, "использование: find <���пути> [-name <���строка>]"
77: "[-mindepth <���целое>] [-maxdepth <���целое>]\n");
78: fprintf(stderr, " [-xdev] [-depth]\n");
79: return 1;
80: }
81:
82: if (argc == 1 || *argv[1] == '-') {
83: argv[1] = ".";
84: argc = 2;
85: }
86:
87: rc = 0;
88: i = 1;
89: flags = 0;
90: while (i < argc && *argv[i] != '-')
91: rc |= nftw (argv [i++], find, 100, flags);
92:
93: return rc;
94: }
14.8. Уведомление о смене каталога
Иногда приложения желают получать уведомления об изменении оглавления каталога. Например, диспетчеры файлов могут выводить оглавление каталога в окне и обновлять это окно каждый раз при изменении каталога другими программами. В то время как приложение регулярно перепроверяет каталог, Linux может послать программе сигнал о модификации каталога, позволяя своевременные обновления без накладных расходов и задержек на страничный обмен.
Системный вызов fcntl()
используется для регистрации уведомлений об обновлениях каталога. В главе 11 уже говорилось о том, что этот системный вызов принимает три аргумента. Первый аргумент — это интересующий файловый дескриптор, второй — это команда, которую необходимо выполнить fcntl()
, а последний — это целое число, специфическое для этой команды. Для уведомлений каталогов первый аргумент является файловым дескриптором, относящимся к интересующему каталогу. Это единственный случай, при котором каталог следует открывать с помощью нормального системного вызова open()
вместо opendir()
. Командой регистрации уведомлений является F_NOTIFY
, а последний аргумент определяет, какие типы событий вызывают отправку сигнала. Это должен быть один или несколько перечисленных ниже флагов, объединенных по логическому "ИЛИ".
DN_ACCESS |
Файл в каталоге, который читается. |
DN_ATTRIB |
Права владения или доступа к файлу в каталоге были изменены. |
DN_CREATE |
В каталоге создан новый файл (включая новые жесткие ссылки на уже существующие файлы). |
DN_DELETE |
Файл удален из каталога. |
DN_MODIFY |
Файл в каталоге был модифицирован (тип модификации — усечение). |
DN_RENAME |
Файл в каталоге был переименован. |
Для отмены уведомления о событии вызовите fcntl()
с командой F_NOTIFY
и последним аргументом, равным нулю.
Обычно уведомление каталога автоматически отменяется после передачи одного сигнала. Для эффективного уведомления каталога окончательный аргумент для fcntl()
должен быть объединен операцией "ИЛИ" с DN_MULTISHOT
, что вызывает отправку сигналов для всех подходящих событий до отмены уведомления.
По умолчанию для уведомления каталога передается SIGIO
. Если приложение желает использовать для этого другой сигнал (например, для разных каталогов могут понадобиться разные сигналы), можно применить команду F_SETSIG
в fcntl()
, а в качестве последнего аргумента определить нужный сигнал. Если используется F_SETSIG
(даже если установлен сигнал SIGIO
), ядро также помещает файловый дескриптор на каталог в элементе si_fd
аргумента обработчика сигналов siginfo_t
[103] Это то же, что и метод, используемый для владения файлами (глава 13).
, позволяя приложению узнать, какие из контролируемых каталогов обновились [104] Обработчик сигналов все еще следует регистрировать с помощью флага SA_SIGINFO , чтобы файловый дескриптор надлежащим образом получил доступ к сигналу.
.
Читать дальше