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

Троан Эрик В.

Шрифт:

330: src++;

331: if (!*src) {

332: freeJob(job);

333: fprintf(stderr, "после \\ ожидался символ\n");

334: return 1;

335: }

336: if (* src == '*' || *srс == '[' | | *src == ']'

337: || *srс == '?')

338: *buf++ = '\\';

339: /* сквозная обработка */

340: default:

341: *buf++ = *src;

Для заключения знаков универсализации в кавычки здесь был добавлен тот же самый код.

Эти две кодовые последовательности обеспечивают передачу каждого аргумента в

glob
без поиска неожиданных совпадений.

Теперь добавим функцию

globLastArgument
, которая универсализирует самый последний аргумент для дочерней программы и замещает его любым найденным совпадением.

Для облегчения управления памяти к

struct childProgram
добавляется элемент
globResult
типа
glob_t
, используемый для хранения результатов всех операций универсализации. Кроме того, добавляется целочисленный элемент
freeGlob
, не равный нулю, если
freeJob
должна освободить
globResult
. Ниже показано полное описание
struct childProgram
в
ladsh3.c
.

35: struct childProgram {

36: pid; /* 0, если завершена */

37: char ** argv; /* имя и аргументы программы */

38: int numRedirections; /* элементы в массиве перенаправлений */

39: struct redirection Specifier * redirections; /* перенаправления ввода-вывода */

40: glob_t globResult; /* результат универсализации параметров */

41: int freeGlob; /* нужно ли освобождать globResult? */

42: };

Во время первого запуска для командной строки функция

globLastArgument
(когда
argc
для текущей дочерней оболочки равно 1) инициализирует
globResult
. Для остальных аргументов она пользуется преимуществом
GLOB_APPEND
для добавления новых совпадений к существующим. Это избавляет от необходимости распределения собственной памяти для целей универсализации, поскольку одиночный
glob_t
при необходимости автоматически расширяется.

Если

globLastArgument
не находит совпадений, символы
\
с кавычками удаляются из аргумента. В противном случае все новые совпадения копируются в список аргументов, создаваемый для дочерней программы.

Ниже приведена полная реализация

globLastArgument
. Все сложные ее части относятся к управлению памятью; фактическая универсализация похожа на реализованную в программе
globit.с
, которая представлена ранее в главе.

 87: void globLastArgument(struct childProgram * prog, int * argcPtr,

 88: int * argcAllocedPtr) {

 89: int argc = *argcPtr;

 90: int argcAlloced = *argcAllocedPtr;

 91: int rc;

 92: int flags;

 93: int i;

 94: char * src, * dst;

 95:

 96: if (argc >1) {/* cmd->globResult уже инициализирован */

 97: flags = GLOB_APPEND;

 98: i = prog->globResult.gl_pathc;

 99: } else {

100: prog->freeGlob = 1;

101: flags = 0;

102: i = 0;

103: }

104:

105: rc = glob(prog->argv[argc - 1], flags, NULL, &prog->globResult);

106: if (rc == GLOB_NOSPACE) {

107: fprintf (stderr, "не хватает памяти для выполнения универсализации\n");

108: return;

109: } else if (rc == GLOB_NOMATCH ||

110: (!rc && (prog->globResult.gl_path - i) == 1 &&

111: !strcmp(prog->argv[argc - 1],

112: prog->globResult.gl_pathv[i]))) {

113: /* необходимо удалить кавычки в \, если они все еще присутствуют */

114: src = dst = prog->argv[argc - 1];

115: while (*src) {

116: if (*src ! = '\\') *dst++ = *src;

117: src++;

  • Читать дальше
  • 1
  • ...
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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