Linux программирование в примерах
Часть 179 из 253 Информация о книге
struct dirent dp;DIR *dir;char pattern[100];/* ...заполнить шаблон, открыть каталог, проверить ошибки... */while ((dp = readdir(dir)) != NULL) {if (fnmatch(pattern, dir->d_name, FNM_PERIOD) == 0)/* имя файла соответствует шаблону */elsecontinue; /* не соответствует */}GNU
используетlsдля реализации своей опцииfnmatch(). Вы можете предоставить несколько игнорируемых шаблонов (с помощью нескольких опций).--ignoreсопоставляет каждое имя файла со всеми шаблонами. Она делает это с помощью функцииlsвfile_interesting():ls.с2269 /* Возвращает не ноль, если файл в 'next' должен быть перечислен. */22702271 static int2272 file_interesting(const struct dirent *next)2273 {2274 register struct ignore_pattern* ignore;22752276 for (ignore = ignore_patterns; ignore; ignore = ignore->next)2277 if (fnmatch(ignore->pattern, next->d_name, FNM_PERIOD) == 0)2278 return 0;22792280 if (really_all_files2281 || next->d_name[0] !=2282 || (all_files2283 && next->d_name[1] != '\0 '2284 && (next->d_name[1] || next->d_name[2] != '\0')))2285 return 1;22862287 return 0;2288 }Цикл в строках 2276–2278 сопоставляет имя файла со списком шаблонов для игнорируемых файлов. Если один из шаблонов подходит, файл не интересен и
возвращает false (то есть 0).file_interesting()Переменная
соответствует опцииall_files, которая показывает файлы, имена которых начинаются с точки, но не являются '-А' и '.'. Переменная..соответствует опцииreally_all_files, которая предполагает-а, а также показывает '-А' и '.'. При наличии таких сведений, условие в строках 228–2284 может быть представлено следующим псевдокодом:..if (/* <i>показать все файлы независимо от их имени (-а)</i> */OR /* <i>первый символ имени не точка</i> */OR (/* <i>показать файлы с точкой (-А)</i> */AND /* <i>в имени файла несколько символов</i> */AND (/* <i>второй символ не точка</i> */OR /* <i>третий символ не завершает имя</i> */)))return TRUE;ЗАМЕЧАНИЕ.
может оказаться дорогостоящей функцией, если она используется в локали с многобайтным набором символов. Обсудим многобайтные наборы символов в разделе 13.4 «Можете произнести это для меня по буквам?»fnmatch()12.7.2. Раскрытие имени файла:
иglob()globfree()Функции
иglob()более разработанные, чемglobfree():fnmatch()#include <glob.h> /* POSIX */int glob(const char *pattern, int flags,int (*errfunc)(const char *epath, int eerrno), glob_t *pglob);void globfree(glob_t *pglob);Функция
осуществляет просмотр каталога и сопоставление с шаблонами, возвращая список всех путей, соответствующихglob(). Символы подстановки могут быть включены в нескольких местах пути, а не только в качестве последнего компонента (например, 'pattern'). Аргументы следующие:/usr/*/*.soconst char *patternШаблон для раскрывания.
int flagsФлаги, управляющие поведением
, вскоре будут описаны.glob()int (*errfunc)(const char *epath, int eerrno)Указатель на функцию для использования при сообщениях об ошибках. Это значение может равняться
. Если нет и еслиNULLвозвращает ненулевое значение или в(*errfunc)()установленflags,GLOB_ERRпрекращает обработку. Аргументамиglob()являются путь, вызвавший проблему, и значение errno, установленное функциями(*errfunc)(),opendir()илиreaddir().stat()glob_t *pglobУказатель на структуру
, использующуюся для хранения результатов. Структураglob_tсодержит список путей, которые выдаетglob_t:glob()typedef struct { /* POSIX */size_t gl_pathc; /* Число найденных подходящих путей */char **gl_pathv; /* Список подходящих путей */size_t gl_offs; /* Слоты для резервирования в gl_pathv */} glob_t;size_t gl_pathcЧисло путей, которые подошли.