113: /* необходимо удалить кавычки в \, если они все еще присутствуют */
114: src = dst = prog->argv[argc - 1];
115: while (*src) {
116: if (*src ! = '\\') *dst++ = *src;
117: src++;
118: }
119: *dst = '\0';
120: } else if (!rc) {
121: argcAlloced += (prog->globResult.gl_pathc - i);
122: prog->argv = realloc(prog->argv,
123: argcAlloced * sizeof(*prog->argv));
124: memcpy(prog->argv + (argc - 1),
125: prog->globResult.gl_pathv + i,
126: sizeof(*(prog->argv)) *
127: (prog->globResult.gl_pathc - i));
128: argc += (prog->globResult.gl_pathc - i - 1);
129: }
130:
131: *argcAllocedPtr = argcAlloced;
132: *argcPtr = argc;
133: }
Последними изменениями касаются вызовов globLastArgument()
, которые должны совершаться после синтаксического разбора нового аргумента. Вызовы добавляются в двух местах: когда за пределами строки в кавычках найдены пробелы и когда вся командная строка разобрана. Оба вызова выглядят следующим образом:
globLastArgument(prog, &argc, &argvAlloced);
Полный код ladsh3.с
доступен на Web-сайте издательства, а также на сайте, посвященном книге.
14.7. Обход деревьев файловых систем
Существуют две функции, которые облегчают приложениям просмотр всех файлов каталога, включая файлы в подкаталогах. Рекурсивный просмотр всех элементов древовидной структуры (например, файловой системы) часто называется обходом (walk) дерева и он реализуется функциями ftw()
и nftw()
. nftw()
представляет собой усовершенствованную версию ftw
.
14.7.1. Использование ftw()
#include
int ftw(const char *dir, ftwFunctionPointer callback, int depth);
Функция ftw()
начинает с каталога dir
и вызывает указанную в callback
функцию для каждого файла в этом каталоге и его подкаталогах. Функция вызывается для всех типов файлов, включая символические ссылки и каталоги. Реализация ftw()
открывает каждый найденный каталог (с помощью файлового дескриптора) и для увеличения производительности не закрывает их, пока не закончит чтение всех элементов каталога. Это означает, что он использует количество файловых дескрипторов, равное количеству уровней подкаталогов. Чтобы предотвратить недостаток файловых дескрипторов в приложении, параметр depth
ограничивает количество файловых дескрипторов ftw()
, остающихся одновременно открытыми. Если этот предел достигается, производительность снижается, поскольку каталоги необходимо часто открывать и закрывать.
Функция, на которую указывает callback
, определяется следующим образом:
int ftwCallbackFunction(const char * file, const struct stat * sb, int flag);
Эта функция вызывается один раз для каждого файла в дереве каталогов, а первый параметр, file
, представляет собой имя файла, начинающееся с dir
, которое передается ftw()
. Например, если бы аргумент dir
принимал значение .
, одним из файловых имен было бы ./bashrc
. Если бы вместо этого использовалось /etc
, имя файла выглядело бы как /etc/hosts
.
Следующий аргумент обратного вызова, sb
, указывает на структуру struct stat
как на результат применения stat()
к файлу[102]. Аргумент flag
предоставляет информацию о файле и принимает одно из следующих значений.