Разработка приложений в среде Linux. Второе издание
Шрифт:
#include <glob.h>
int glob(const char * pattern, int flags,
int (*errfunc)(const char * epath, int eerrno), glob_t* pglob);
Первый параметр,
pattern
, определяет шаблон, которому должны соответствовать имена файлов. В нем допускается применение операций универсализации *
, ?
и []
, а также необязательно {
, }
и ~
которые трактуются так же, как в стандартных оболочках. Последний параметр указывает на структуру, которая заполняется результатами универсализации. Эта структура определена следующим образом. #include <glob.h>
typedef struct {
int gl_pathc; /* количество путей
в gl_pathv */
char **gl_pathv; /* список gl_pathc, соответствующих именам путей */
int gl_offs; /* пространство, зарезервированное в gl_pathv для GLOB_DOOFFS*/
} glob_t;
flags
— это одно или несколько перечисленных ниже значений, объединенных с помощью битового "ИЛИ". GLOB_ERR | Возвращается в случае ошибки (если функция не может прочесть оглавление каталога, например, из-за проблем с доступом). |
GLOB_MARK | Если шаблон соответствует имени каталога, при возврате к этому имени будет добавлен символ / . |
GLOB_NOSORT | Обычно возвращаемые имена путей сортируются в алфавитном порядке. Если этот флаг установлен, они не сортируются. |
GLOB_DOOFFS | При установке первые строки pglob->gl_offs в возвращаемом списке имен путей оставляются пустыми. Это позволяет использовать glob во время выстраивания ряда аргументов, которые будут переданы прямо в execv . |
GLOB_NOCHECK | Если ни одно из файловых имен не соответствует шаблону, в качестве единственного совпадения возвращается сам шаблон (обычно не возвращается ни одного совпадения). В обоих случаях шаблон возвращается, если он не содержит операций универсализации. |
GLOB_APPEND | pglob предположительно является действительным результатом предыдущего вызова glob , и любые результаты этого вызова добавляются к результатам предыдущего вызова. Это облегчает универсализацию множества шаблонов. |
GLOB_NOESCAPE | Обычно если операции универсализации предшествует символ \ , она воспринимается как обычный символ. Например, шаблон а\* обычно соответствует только файлу по имени а* . Если устанавливается GLOB_NOESCAPE , символ \ теряет свое особое значение, aa\* соответствует любому имени файла, начинающемуся с символов а\ . В таком случае имена а\. и a\bcd будут соответствовать, но arachnid — нет, поскольку оно не содержит \ . |
GLOB_PERIOD | Большинство оболочек не позволяют применять операции универсализации для файловых имен, начинающихся с . (запустите ls * в своем домашнем каталоге и сравните полученное с результатом ls - а . ). Функция glob обычно ведет себя подобным образом, но GLOB_PERIOD позволяет операциям универсализации работать с ведущим символом. Значение GLOB_PERIOD в POSIX не определено. |
GLOB_BRACE | Многие оболочки (следуя примеру csh ) разворачивают последовательности с фигурными скобками как альтернативы; например, шаблон {a, b} разворачивается до a b , а шаблон a {, b, c} — до a ab ас . GLOB_BRACE делает возможным такое поведение. Значение GLOB_BRACE в POSIX не определено. |
GLOB_NOMAGIС | Действует подобно GLOB_NOCHECK за исключением того, что он добавляет шаблон к списку результатов только в том случае, если она не содержит специальных знаков. Значение GLOB_NOMAGIC в POSIX не определено. |
GLOB_TILDE | Включает расширение с тильдой, в котором ~ или подстрока ~/ разворачиваются до пути к домашнему каталогу текущего пользователя, а ~user — до пути к домашнему
GLOB_TILDE в POSIX не определено. |
GLOB_ONLYDIR | Совпадает только с каталогами, а не с другими типами файлов. Значение GLOB_ONLYDIR в POSIX не определено. |
Часто
glob
наталкивается на каталоги, к которым у процесса нет доступа, что вызывает ошибки. Хотя ошибку можно каким-то образом обработать, однако если glob
возвращает ошибку (GLOB_ERR
), операцию универсализации нельзя перезапустить там, где предыдущая операция универсализации столкнулась с ошибкой. Поскольку сложно одновременно устранять ошибки, происходящие во время выполнения glob
, и завершать универсализацию, glob
позволяет передать ошибку в специально предусмотренную для этого функцию, которая определяется в третьем параметре glob
. Прототип этой функции показан ниже.
int globerr(const char * pathname, int globerrno);
Функции передается путевое имя, вызвавшее ошибку, и значение
errno
, возвращенное одним из системных вызовов opendir
, readdir
или stat
. Если функция ошибки возвращает величину больше нуля, glob
возвращается с ошибкой. В противном случае операция универсализации продолжается. Результаты универсализации хранятся в структуре
glob_t
, на которую ссылается pglob
. Она включает описанные ниже элементы, позволяющие абоненту найти согласованные имена файлов. gl_pathc | Количество путевых имен, соответствующих шаблону. |
gl_pathv | Массив путевых имен, соответствующих шаблону. |
После использования возвращенного результата
glob_t
занимаемую им память следует освободить, передав его в globfree
. void globfree(glob_t * pglob);
Системный вызов
glob
возвращает GLOB_NOSPACE
в случае нехватки памяти, GLOB_ABEND
, если ошибка чтения привела к неудачному выполнению функции, GLOB_NOMATCH
, если соответствия не были найдены, или 0
, если функция выполнилась удачно и нашла соответствия. Для иллюстрации работы
glob
ниже приведена программа globit
, которая принимает множество шаблонов в качестве аргументов, универсализирует их и отображает результат. В случае ошибки отображается сообщение, описывающее ошибку, а операция универсализации продолжается. 1: /* globit.с */
2:
3: #include <errno.h>
4: #include <glob.h>
5: #include <stdio.h>
6: #include <string.h>
7: #include <unistd.h>
8:
9: /* Это функция ошибки, которая передается в glob. Она просто отображает
10: сообщение об ошибке и возвращает состояние успеха, что позволяет glob
11: продолжить работу. */
12: int errfn(const char * pathname, int theerr) {
13: fprintf(stderr, "ошибка при доступе к %s: %s\n", pathname,
14: strerror(theerr));
15:
16: /* Операция универсализации должна продолжаться, поэтому вернуть 0 */
17: return 0;
18: }
19:
20: int main(int argc, const char ** argv) {
21: glob_t result;
22: int i, rc, flags;
23:
24: if (argc < 2) {
25: printf("необходимо передать хотя бы один аргумент\n") ;
26: return 1;
27: }
28:
29: /* установить flags в 0; позже он будет изменен на GLOB_APPEND */
30: flags = 0;
31:
32: /* совершить проход по всем аргументам командной строки */
33: for (i = 1; i < argc; i++) {
34: rc = glob(argv[i], flags, errfn, &result);
35:
36: /* благодаря errfn, GLOB_ABEND не происходит */
Поделиться:
Популярные книги
Возвышение Меркурия. Книга 7
7. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок
1. Сумеречный стрелок
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Мимик нового Мира 6
5. Мимик!
Фантастика:
юмористическая фантастика
попаданцы
рпг
5.00
рейтинг книги
Фиктивный брак
Фантастика:
фэнтези
6.71
рейтинг книги
Совпадений нет
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Кровь на эполетах
3. Штуцер и тесак
Фантастика:
альтернативная история
7.60
рейтинг книги
Лорд Системы 4
4. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Я тебя не предавал
2. Ворон
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Горничная для тирана
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Купидон с топором
Любовные романы:
современные любовные романы
7.67
рейтинг книги
Кодекс Охотника. Книга XXV
25. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Мимик нового Мира 12
11. Мимик!
Любовные романы:
эро литература
5.00
рейтинг книги
Ваше Сиятельство 2
2. Ваше Сиятельство
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Рождение победителя
3. Девятый
Фантастика:
фэнтези
альтернативная история
9.07