Linux программирование в примерах
Шрифт:
struct FTW* s
предоставляет дополнительную информацию, которая может быть полезной. s->bas
e действует в качестве индекса в file
; file
является полным путем обрабатываемого объекта (относительно точки отсчета), 'file + s->base
' указывает на первый символ компонента имени файла. s->level
указывает текущую глубину иерархии; считается, что первоначальная точка отсчета находится на уровне 0. Функция обратного вызова должна вернуть 0, если все нормально. Любое ненулевое возвращенное значение заставляет
nftw
nftw
был шанс произвести очистку: т.е. освободить динамически выделенную память, закрыть открытые дескрипторы файлов и т.д. Функции обратного вызова не следует использовать longjmp
, если только программа не завершается немедленно, (longjmp
является продвинутой функцией, которую мы опишем в разделе 12.5 «Нелокальные goto».) Рекомендуемой методикой обработки ошибок является установка глобальной переменной, указывающей на наличие проблем, возвращение 0 из функции обратного вызова и обработка ошибок после завершения перемещения nftw
по иерархии файлов. (GNU du
это делает, как мы вскоре увидим.) Давайте свяжем все это воедино в примере программы.
ch08-nftw.c
обрабатывает каждый файл или каталог, указанный в командной строке, запуская для них nftw
. Функция, обрабатывающая каждый файл, выводите отступом имя и тип файла, показывая иерархическое положение каждого файла. Для разнообразия мы сначала покажем результаты, а затем покажем и обсудим программу:
$ pwd /* Где мы находимся */
/ home/аrnold/work/prenhall/progex
$ code/ch08/ch08-nftw code /* Обойти каталог 'code' */
code (directory) /* Каталог верхнего уровня */
ch02 (directory) /* Подкаталоги с отступом на один уровень */
ch02-printenv.c (file) /* Файлы в подкаталоге с отступом
на два уровня */
ch03 (directory)
ch03-memaddr.c (file)
ch04 (directory)
ch04-holes.c (file)
ch04-cat.с (file)
ch04-maxfds.c (file)
v7cat.c (file)
...
Вот сама программа:
1 /* ch08-nftw.c --- демонстрирует nftw */
2
3 #define _XOPEN_SOURCE 1 /* Требуется под GLIBC для nftw */
4 #define _XOPEN_SOURCE_EXTENDED 1 /* To же */
5
6 #include <stdio.h>
7 #include <errno.h>
8 #include <getopt.h>
9 #include <ftw.h> /* получает для нас <sys/types.h> и <sys/stat.h> */
10 #include <limits.h> /* для PATH_MAX */
11 #include <unistd.h> /* для объявлений getdtablesize, getcwd */
12
13 #define SPARE_FDS 5 /* fds для использования другими функциями, см. текст */
14
15 extern int process(const char *file, const struct stat *sb,
16 int flag, struct FTW *s);
17
18 /* usage --- print message and die */
19
20 void usage(const char *name)
21 {
22 fprintf(stderr, "usage: %s (-c) directory ...\n", name);
23 exit(1);
24 }
25
26 /* main ---
вызвать nftw для каждого аргумента командной строки */
27
28 int main(int argc, char **argv)
29 {
30 int i, c, nfds;
31 int errors = 0;
32 int flags = FTW_PHYS;
33 char start[PATH_MAX], finish[PATH_MAX];
34
35 while ((c = getopt(argc, argv, "с")) != -1) {
36 switch (c) {
37 case 'c':
38 flags |= FTW_CHDIR;
39 break;
40 default:
41 usage(argv[0]);
42 break;
43 }
44 }
45
46 if (optind == argc)
47 usage(argv[0]);
48
49 getcwd(start, sizeof start);
50
51 nfds = getdtablesize - SPARE_FDS; /* оставить несколько запасных дескрипторов */
52 for (i = optind; i < argc; i++) {
53 if (nftw(argv[i], process, nfds, flags) != 0) {
54 fprintf(stderr, "%s: %s: stopped early\n",
55 argv[0], argv[i]);
56 errors++;
57 }
58 }
59
60 if ((flags & FTW_CHDIR) != 0) {
61 getcwd(finish, sizeof finish);
62 printf("Starting dir: %s\n", start);
63 printf("Finishing dir: %s\n", finish);
64 }
65
66 return (errors != 0);
67 }
Строки 3–11 включают заголовочные файлы. По крайней мере в GLIBC 2.3.2 перед включением любого заголовочного файла необходимы
#define
для _XOPEN_SOURCE
и _XOPEN_SOURCE_EXTENDED
. Они дают возможность получить объявления и значения флагов, которые nftw
предоставляет свыше предоставляемых ftw
. Это специфично для GLIBC. Потребность в этом в конечном счете исчезнет, когда GLIBC станет полностью совместимой со стандартом POSIX 2001.
Поделиться:
Популярные книги
Измена. Ребёнок от бывшего мужа
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Отборная бабушка
Фантастика:
фэнтези
юмористическая фантастика
7.74
рейтинг книги
Мимик нового Мира 3
2. Мимик!
Фантастика:
юмористическая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Адский пекарь
1. Дорогой пекарь!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я еще не князь. Книга XIV
14. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Путь Шедара
4. Другая сторона
Фантастика:
боевая фантастика
6.83
рейтинг книги
С Д. Том 16
16. Сердце дракона
Фантастика:
боевая фантастика
6.94
рейтинг книги
Бывший муж
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Драконий подарок
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Вечный. Книга I
1. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вираж бытия
1. Фрунзе
Фантастика:
героическая фантастика
попаданцы
альтернативная история
6.86
рейтинг книги
Вечный. Книга II
2. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Наследница Драконов
2. Наследница Драконов
Любовные романы:
современные любовные романы
любовно-фантастические романы
6.81
рейтинг книги
Ретроградный меркурий
4. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
5.00