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.
Поделиться:
Популярные книги
Перешагнуть пропасть
1. Перешагнуть пропасть
Фантастика:
боевая фантастика
космическая фантастика
8.38
рейтинг книги
Изгой Проклятого Клана. Том 4
4. Изгой
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Афганский рубеж
1. Рубеж
Фантастика:
попаданцы
альтернативная история
7.50
рейтинг книги
Золотой ворон
5. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Натиск
12. Последняя жизнь
Фантастика:
аниме
фэнтези
попаданцы
6.20
рейтинг книги
Бастард Императора. Том 12
12. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Неучтенный элемент. Том 10
10. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Кукловод
4. Династия
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Лекарь Империи
1. Лекарь Империи
Фантастика:
городское фэнтези
аниме
дорама
фэнтези
попаданцы
5.00
рейтинг книги
География растений
Классики естествознания
Научно-образовательная:
ботаника
7.50
рейтинг книги
На границе империй. Том 10. Часть 8
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
Точка Бифуркации IV
4. ТБ
Фантастика:
героическая фантастика
городское фэнтези
попаданцы
5.00
рейтинг книги
Александри В. Стихотворения. Эминеску М. Стихотворения. Кошбук Д. Стихотворения. Караджале И.-Л. Потерянное письмо. Рассказы. Славич И. Счастливая мельница
126. Библиотека всемирной литературы
Поэзия:
поэзия
5.00
рейтинг книги
Матабар VIII
8. Матабар
Проза:
магический реализм
5.00