Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

14.5.1. Использование подпроцесса

Самый старый метод универсализации предусматривает запуск оболочки в качестве дочернего процесса и указание ей универсализировать файловые имена. Стандартная функция

popen
(см. главу 10) упрощает этот метод — просто запустите команду
ls *.с
с помощью
popen
и прочитайте результат. Этот подход может показаться несколько упрощенным, но все же он обеспечивает переносимое решение проблемы универсализации (вот почему приложения вроде Perl используют его).

Ниже приведена программа, которая универсализирует все аргументы и отображает все совпадения.

 1: /* popenglob.c */

 2:

 3: #include <stdio.h>

 4: #include <string.h>

 5: #include <sys/wait.h>

 6: #include <unistd.h>

 7:

 8: int main(int argc, const char ** argv)

 9: char buf[1024];

10: FILE * ls;

11: int result;

12: int i;

13:

14: strcpy(buf, "ls");

15:

16: for (i = 1; i < argc; i++) {

17: strcat(buf, argv[i]);

18: strcat(buf, " ");

19: }

20:

21: ls = popen(buf, "r");

22: if (!ls) {

23: perror("popen");

24: return 1;

25: }

26:

27: while (fgets(buf, sizeof(buf), ls))

28: printf("%s", buf);

29:

30: result = pclose(ls);

31:

32: if (!WIFEXITED(result)) return 1;

33:

34: return 0;

35: }

14.5.2. Внутренняя универсализация

Если необходимо универсализировать несколько файловых имен, запуск нескольких подоболочек с помощью

popen
будет неэффективным. Функция
glob
позволяет универсализировать имена файлов без запуска каких-либо подпроцессов, однако за счет увеличения сложности и снижения переносимости. Несмотря на то что вызов
glob
описан в стандарте POSIX.2, многие варианты Unix до сих пор его не поддерживают.

#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 — до пути к домашнему каталогу пользователя user. Значение
GLOB_TILDE
в POSIX не определено.
GLOB_ONLYDIR
Совпадает только с каталогами, а не с другими типами файлов. Значение
GLOB_ONLYDIR
в POSIX не определено.

Часто

glob
наталкивается на каталоги, к которым у процесса нет доступа, что вызывает ошибки. Хотя ошибку можно каким-то образом обработать, однако если
glob
возвращает ошибку (
GLOB_ERR
), операцию универсализации нельзя перезапустить там, где предыдущая операция универсализации столкнулась с ошибкой. Поскольку сложно одновременно устранять ошибки, происходящие во время выполнения
glob
, и завершать универсализацию,
glob
позволяет передать ошибку в специально предусмотренную для этого функцию, которая определяется в третьем параметре
glob
.

  • Читать дальше
  • 1
  • ...
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: