Linux программирование в примерах
может быть вызвана более одного раза: при первом вызове флагglob()не должен быть указан, при всех последующих вызовах он должен быть указан. Вы не можете между вызовами изменятьGLOB_APPEND, а если вы изменили какие-нибудь значения вgl_offsилиgl_pathv, нужно их восстановить перед последующим вызовомgl_pathc.glob()Возможность многократного вызова
позволяет накапливать результаты в одном списке. Это довольно практично, приближается к мощным возможностям раскрывания групповых символов оболочки, но на уровне языка программирования С.glob()возвращает 0, если не было проблем, или одно из значений из табл. 12.4, если были.glob()Таблица 12.4. Возвращаемые
значенияglob()
Флаг Значение GLOB_ABORTEDПросмотр остановлен раньше времени, поскольку был установлен или функцияGLOB_ERRвозвратила ненулевой результат(*errfunc)()GLOB_NOMATCHНи одно имя файла не соответствовало , а флагpatternне был установленGLOB_NOCHECKGLOB_NOSPACEБыла проблема с выделением динамической памяти освобождает всю память, которую динамически выделилаglobfree()Следующая программа,glob(), демонстрируетch12-glob.с:glob()1 /* ch12-glob.c --- демонстрирует glob(). */23 #include <stdio.h>4 #include <errno.h>5 #include <glob.h>67 char *myname;89 /* globerr --- выводит сообщение об ошибке для glob() */1011 int globerr(const char *path, int eerrno)12 {13 fprintf(stderr, "%s: %s: %s\n", myname, path, strerror(eerrno));14 return 0; /* let glob() keep going */15 }1617 /* main() --- раскрывает символы подстановки в командной строке и выводит результаты */1819 int main(int argc, char **argv)20 {21 int i;22 int flags = 0;23 glob_t results;24 int ret;2526 if (argc == 1) {27 fprintf(stderr, "usage: %s wildcard ...\n", argv[0]);28 exit(1);29 }3031 myname = argv[0]; /* для globerr() */3233 for (i = 1; i < argc; i++) {34 flags |= (i > 1 ? GLOB_APPEND : 0);35 ret = glob(argv[i], flags, globerr, &results);36 if (ret != 0) {37 fprintf(stderr, "%s: problem with %s (%s),38 stopping early\n", myname, argv[i],39 /* опасно: */ (ret == GLOB_ABORTED ? "filesystem problem" :40 ret == GLOB_NOMATCH ? "no match of pattern" :41 ret == GLOB_NOSPACE ? "no dynamic memory" :42 "unknown problem"));43 break;44 }45 }4647 for (i = 0; i < results.gl_pathc; i++)48 printf("%s\n", results.gl_pathv[i]);4950 globfree(&results);51 return 0;52 }Строка 7 определяет
, которая указывает на имя программы; эта переменная для сообщений об ошибках отmyname, определенной в строках 11–15.globerr()Строки 33–45 являются основой программы. Они перебирают в цикле шаблоны, приведенные в командной строке, вызывая для каждого
для добавления к списку результатов. Большую часть цикла составляет обработка ошибок (строки 36–44). Строки 47–48 выводят результирующий список, а строки 50–51 проводят завершающую очистку и возвращаются.glob()Строки 39–41 не являются хорошими; нужно было использовать отдельную функцию, преобразующую целые константы в строки; мы сделали это главным образом ради экономии места. Код наподобие этого может быть сносным для небольших программ, но более крупные должны использовать функцию.
Если вы подумаете о работе, происходящей под капотом (открытие и чтение каталогов, сопоставление шаблонов, динамическое выделение памяти для увеличения списка, сортировка списка), можете качать ценить, как много для вас делает
! Вот некоторые результаты:glob()$ <b>ch12-glob '/usr/lib/x*.so' '../../*.texi'</b>/usr/lib/xchat-autob5.so/usr/lib/xchat-autogb.so../../00-preface.texi../../01-intro.texi../../02-cmdline.texi