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

Троан Эрик В.

Шрифт:

708: /* задание выполняется на переднем плане; ожидать его */

709: i = 0;

710: while (!jobList.fg->progs[i].pid ||

711: jobList.fg->progs[i].isStopped) i++;

712:

713: waitpid(jobList.fg->progs[i].pid, &status, WUNTRACED);

714:

715: if (WIFSIGNALED(status) &&

716: (WTERMSIG(status) != SIGINT)) {

717: printf("%s\n", strsignal(status));

718: }

719:

720: if (WIFEXITED(status) || WIFSIGNALED(status)) {

721: /* дочерний процесс завершен */

722: jobList.fg->runningProgs--;

723: jobList.fg->progs[i].pid = 0;

724:

725: if (!jobList.fg->runningProgs) {

726: /* дочерний процесс завершен */

727:

728: removeJob(&jobList, jobList.fg);

729: jobList. fg = NULL;

730:

731: /* переместить оболочку на передний план */

732: if (tcsetpgrp (0, getpid))

733: perror("tcsetpgrp");

734: }

735: } else {

736: /* дочерний процесс остановлен */

737: jobList.fg->stoppedProgs++;

738: jobList.fg->progs[i].isStopped = 1;

739:

740: if (jobList.fg->stoppedProgs ==

741: jobList.fg->runningProgs) {

742: printf ("\n" JOB_STATUS_FORMAT,

743: jobList.fg->jobId,

744: "Остановлен", jobList.fg->text);

745: jobList.fg = NULL;

746: }

747: }

748:

749: if (!jobList.fg) {

750: /* переместить оболочку на передний план */

751: if (tcsetpgrp (0, getpid))

752: perror("tcsetpgrp");

753: }

754: }

Подобным образом фоновые задания могут прерываться с помощью сигналов. Мы снова добавляем

WUNTRACED
к
waitpid
, что проверяет состояния фоновых процессов. После остановки фонового процесса обновляются флаг
isStopped
и счетчик
stoppedProgs
, а в случае остановки всего задания выводится сообщение.

Последняя возможность, требуемая для

ladsh
— перемещение задания между состоянием выполнения на переднем плане, состоянием выполнения в фоне и остановом. Это делается с помощью двух встроенных команд:
fg
и
bg
. Они являются ограниченными версиями нормальных команд оболочки, носящих те же имена. Оба принимают один параметр, являющийся номером задания, которому предшествует знак
%
(для совместимости со стандартными оболочками). Команда
fg
перемещает определенное задание на передний план, a
bg
запускает его в фоне.

Обе операции выполняются передачей

SIGCONT
каждому процессу в активизируемой группе процессов. Поскольку этот сигнал может передаваться каждому процессу с помощью отдельных вызовов
kill
, несколько проще передать его всей группе процессов, используя отдельный вызов
kill
. Ниже приведена реализация встроенных команд
fg
и
bg
.

461: } else if (! strcmp(newJob.progs[0].argv[0], "fg") ||

462: !strcmp(newJob.progs[0].argv[0], "bg")) {

463: if (!newJob.progs[0].argv[1] || newJob.progs[0].argv[2]) {

464: fprintf(stderr,

465: "%s: ожидался в точности один аргумент\n",

466: newJob.progs[0].argv[0]);

467: return 1;

468: }

469:

470: if (sscanf(newJob.progs[0].argv[l], "%%%d", &jobNum) != 1)

471: fprintf(stderr, "%s: ошибочный аргумент '%s'\n",

  • Читать дальше
  • 1
  • ...
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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