FTW_DP | Этот элемент является каталогом, об оглавлении которого уже сообщили (это может произойти только в случае установки FTW_DEPTH ). |
FTW_SLN | Этот элемент является символической ссылкой, указывающей на несуществующий файл (поврежденная ссылка). Это происходит только в том случае, если FTW_PHYS не был установлен; если же он был установлен, передается FTW_SL . |
Эти дополнительные значения flag
надлежащим образом определяют nftw()
для символических ссылок. При использовании FTW_PHYS
все символические ссылки возвращают FTW_SL
. Без nftw()
поврежденные ссылки выдают FTW_NS
, а другие символические ссылки дают тот же результат, что и цель ссылки.
Обратный вызов для nftw()
принимает еще один аргумент, ftwInfо
. Это указатель на struct FTW
, которая определяется следующим образом.
#define _XOPEN_SOURCE 600
#include
struct FTW {
int base;
int level;
};
Элемент base
— это смещение имени файла в полном пути, передаваемое обратному вызову. Например, если переданный полный путь выглядит как /usr/bin/ls
, base
будет равно 9, a file + ftwInfo->base
даст имя файла ls
. level
— это количество каталогов под текущим каталогом. Если ls
был найден в nftw()
, начинающемся с /usr
, уровень будет равен 1. Если поиск начался с /usr/bin
, уровень будет равен 0.
14.7.3. Реализация find
Команда find
выполняет в одном или нескольких деревьях каталогов поиск файлов, соответствующих определенным характеристикам. Ниже приведена простая реализация find
, реализованная на основе nftw()
. Она использует fnmatch()
(см. главу 23) для реализации переключателя -name
и иллюстрирует многие флаги, воспринимаемые nftw()
.
1: /* find.с */
2:
3: #define _XOPEN_SOURCE 600
4:
5: #include
6: #include
7: #include
8: #include
9: #include
10: #include
11:
12: const char * name = NULL;
13: int minDepth = 0, maxDepth = INT_MAX;
14:
15: int find (const char * file, const struct stat * sb, int flags,
16: struct FTW * f) {
17: if (f->level < minDepth) return 0;
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++;