Чтение онлайн

на главную - закладки

Жанры

Разработка приложений в среде 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++;

118: }

119: *dst = '\0';

120: } else if (!rc) {

121: argcAlloced += (prog->globResult.gl_pathc - i);

122: prog->argv = realloc(prog->argv,

123: argcAlloced * sizeof(*prog->argv));

124: memcpy(prog->argv + (argc - 1),

125: prog->globResult.gl_pathv + i,

126: sizeof(*(prog->argv)) *

127: (prog->globResult.gl_pathc - i));

128: argc += (prog->globResult.gl_pathc - i - 1);

129: }

130:

131: *argcAllocedPtr = argcAlloced;

132: *argcPtr = argc;

133: }

Последними изменениями касаются вызовов

globLastArgument
, которые должны совершаться после синтаксического разбора нового аргумента. Вызовы добавляются в двух местах: когда за пределами строки в кавычках найдены пробелы и когда вся командная строка разобрана. Оба вызова выглядят следующим образом:

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

Дракон с подарком

Суббота Светлана
3. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
6.62
рейтинг книги
Дракон с подарком

Бывшие. Война в академии магии

Берг Александра
2. Измены
Любовные романы:
любовно-фантастические романы
7.00
рейтинг книги
Бывшие. Война в академии магии

Мастер клинков. Начало пути

Распопов Дмитрий Викторович
1. Мастер клинков
Фантастика:
фэнтези
9.16
рейтинг книги
Мастер клинков. Начало пути

Имя нам Легион. Том 8

Дорничев Дмитрий
8. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 8

Измена. Право на счастье

Вирго Софи
1. Чем закончится измена
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на счастье

Начальник милиции 2

Дамиров Рафаэль
2. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции 2

Камень. Книга 4

Минин Станислав
4. Камень
Фантастика:
боевая фантастика
7.77
рейтинг книги
Камень. Книга 4

Измена. Мой заклятый дракон

Марлин Юлия
Любовные романы:
любовно-фантастические романы
7.50
рейтинг книги
Измена. Мой заклятый дракон

Предатель. Цена ошибки

Кучер Ая
Измена
Любовные романы:
современные любовные романы
5.75
рейтинг книги
Предатель. Цена ошибки

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Рождение победителя

Каменистый Артем
3. Девятый
Фантастика:
фэнтези
альтернативная история
9.07
рейтинг книги
Рождение победителя

Барону наплевать на правила

Ренгач Евгений
7. Закон сильного
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Барону наплевать на правила

Камень. Книга шестая

Минин Станислав
6. Камень
Фантастика:
боевая фантастика
7.64
рейтинг книги
Камень. Книга шестая

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь