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

Троан Эрик В.

Шрифт:

11.7.2. Изменения в коде

Как только в

parseCommand
будут правильно отражены структуры данных, то запуск команд в правильном порядке становится довольно простым при достаточном внимании к деталям. Прежде всего, мы добавляем цикл в
parseCommand
для запуска дочерних процессов, поскольку теперь их может быть множество. Прежде чем войти в цикл, мы устанавливаем
nextin
и
nextout
, которые являются файловыми дескрипторами, используемыми в качестве стандартных потоков ввод и вывода для следующего запускаемого процесса. Для начала мы используем те же stdin и stdout, что и оболочка.

Теперь посмотрим, что происходит внутри цикла. Основная идея описана ниже.

1. Если это финальный процесс в задании, убедиться, что

nextout
указывает на stdout. В противном случае нужно подключить вывод этого задания к входному концу неименованного канала.

2. Породить новый процесс. Внутри дочернего перенаправить stdin и stdout, как указано с помощью

nextin
,
nextout
и всех специфицированных ранее перенаправлений.

3. Вернувшись обратно в родительский процесс, закрыть

nextin
и
nextout
, используемые только что запущенным дочерним процессом (если только они не являются потоками ввода и вывода самой оболочки).

4. Теперь настроить следующий процесс в задании для приема его ввода из вывода процесса, который мы только что создали (через

nextin
).

Вот как эти идеи перевести на С.

365: nextin=0, nextout=1;

366: for (i=0; i<newJob.numProgs; i++) {

367: if ((i+1) < newJob.numProgs) {

368: pipe(pipefds);

369: nextout = pipefds[1];

370: } else {

371: nextout = 1;

372: }

373:

374: if (!(newJob.progs[i].pid = fork)) {

375: if (nextin != 0) {

376: dup2(nextin, 0);

377: close(nextin);

378: }

379:

380: if (nextout != 1) {

381: dup2(nextout, 1);

382: close(nextout);

383: }

384:

385: /* явное перенаправление перекрывает каналы */

386: setupRedirections(newJob.progs+i);

387:

388: execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);

389: fprintf(stderr, "exec of %s failed: %s\n",

390: newJob.progs[i].argv[0],

391: strerror(errno));

392: exit(1);

393: }

394:

395: /* поместить наш дочерний процесс в группу процессов,

396: чей лидер - первый процесс канала */

397: setpgid(newJob.progs[i].pid, newJob.progs[0].pid);

398:

399: if (nextin != 0) close(nextin);

400: if (nextout != 1) close (nextout);

401:

402: /* Если больше нет процессов, то nextin - мусор,

403: но это не имеет значения */

404: nextin = pipefds[0];

Единственный код, добавленный в

ladsh2.с
для обеспечения перенаправлений — это функция
setupRedirections
, код которой останется неизменным во всех последующих версиях
ladsh
. Ее задача состоит в обработке спецификаторов
struct redirectionSpecifier
для дочерних заданий и соответствующей модификации дочерних файловых дескрипторов. Мы рекомендуем просмотреть код этой функции в приложении Б.

Глава 12

Обработка сигналов

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

  • Читать дальше
  • 1
  • ...
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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