Разработка приложений в среде Linux - [210]

Шрифт
Интервал

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

>547:

>548:   /* закрываем канал управления, чтобы продолжить работу дочернего процесса */

>549:   close(controlfds[0]);

>550:   close(controlfds[1]);

>551:

>552:   if (nextin !=0) close(nextin);

>553:   if (nextout !=1) close(nextout);

>554:

>555:   /* Если другого процесса нет, то nextin является "мусором",

>556:      хотя это и не является помехой */

>557:   nextin = pipefds[0];

>558:  }

>559:

>560:  newJob.pgrp = newJob.progs[0].pid;

>561:

>562:  /* поиск идентификатора используемого задания */

>563:  newJob.jobld = 1;

>564:  for (job = jobList->head; job; job = job->next)

>565:   if (job->jobId> = newJob.jobId)

>566:    newJob.jobId = job->jobId + 1;

>567:

>568:  /* добавляем задание в список выполняющихся заданий */

>569:  if (!jobList->head) {

>570:   job = jobList->head = malloc(sizeof(*job));

>571:  } else {

>572:   for (job = jobList->head; job->next; job = job->next);

>573:   job->next = malloc(sizeof(*job));

>574:   job = job->next;

>575:  }

>576:

>577:  *job = newJob;

>578:  job->next = NULL;

>579:  job->runningProgs = job->numProgs;

>580:  job->stoppedProgs = 0;

>581:

>582:  if (inBg) {

>583:   /* мы не ожидаем возврата фоновых заданий - добавляем их

>584:      в список фоновых заданий и оставляем их */

>585:

>586:   printf("[%d] %d\n", job->jobId,

>587:    newJob.progs[newJob.numProgs - 1].pid);

>588:  } else {

>589:   jobList->fg = job;

>590:

>591:   /* перемещаем новую группу процессов на передний план */

>592:

>593:   if (tcsetpgrp(0, newJob.pgrp))

>594:    perror("tcsetpgrp");

>595:  }

>596:

>597:  return 0;

>598: }

>599:

>600: void removeJob(struct jobSet * jobList, struct job * job) {

>601:  struct job * prevJob;

>602:

>603:  freeJob(job);

>604:  if (job == jobList->head) {

>605:   jobList->head = job->next;

>606:  } else {

>607:   prevJob = jobList->head;

>608:   while (prevJob->next != job) prevJob = prevJob->next;

>609:   prevJob->next = job->next;

>610:  }

>611:

>612:  free(job);

>613: }

>614:

>615: /* Проверяем, завершился ли какой-либо фоновый процесс - если да, то

>616:    устанавливаем причину и проверяем, окончилось ли выполнение задания */

>617: void checkJobs(struct jobSet * jobList) {

>618:  struct job * job;

>619:  pid_t childpid;

>620:  int status;

>621:  int progNum;

>622:  char * msg;

>623:

>624:  while ((childpid = waitpid(-1, &status,

>625:   WNOHANG | WUNTRACED)) > 0) {

>626:   for (job = jobList->head; job; job = job->next) {

>627:    progNum = 0;

>628:    while(progNum < job->numProgs &&

>629:     job->progs[progNum].pid != childpid)

>630:     progNum++;

>631:    if (progNum < job->numProgs) break;

>632:   }

>633:

>634:   if (WIFEXITED(status) || WIFSIGNALED(status)) {

>635:    /* дочерний процесс завершил работу */

>636:    job->runningProgs--;

>637:    job->progs[progNum].pid = 0;

>638:

>639:    if (!WIFSIGNALED(status))

>640:     msg = "Завершено";

>641:    else

>642:     msg = strsignal(WTERMSIG(status));

>643:

>644:    if (!job->runningProgs) {

>645:     printf(JOB_STATUS_FORMAT, job->jobId,

>646:      msg, job->text);

>647:     removeJob(jobList, job);

>648:    }

>649:   } else {

>650:    /* выполнение дочернего процесса остановлено */

>651:    job->stoppedProgs++;

>652:    job->progs[progNum].isStopped = 1;

>653:

>654:    if (job->stoppedProgs == job->numProgs) {

>655:     printf(JOB_STATUS_FORMAT, job->jobId, "Остановлено",

>656:      job->text);

>657:    }

>658:   }

>659:  }

>660:

>661:  if (childpid == -1 && errno != ECHILD)

>662:   perror("waitpid");

>663: }

>664:

>665: int main(int argc, const char ** argv) {

>666:  char command[MAX_COMMAND_LEN + 1];

>667:  char * nextCommand = NULL;

>668:  struct jobSet jobList = { NULL, NULL };

>669:  struct job newJob;

>670:  FILE * input = stdin;

>671:  int i;

>672:  int status;

>673:  int inBg;

>674:

>675:  if (argc > 2) {

>676:   fprintf(stderr, "неожиданный аргумент; использование: ladsh1 "

>677:    "<команды>\n");

>678:   exit(1);

>679:  } else if (argc == 2) {

>680:   input = fopen(argv[1], "r");

>681:   if (!input) {

>682:    perror("fopen");

>683:    exit(1);

>684:   }

>685:  }

>686:

>687:  /* не обращаем внимания на этот сигнал; это просто помеха,

>688:     не имеющая никакого значения для оболочки */

>689:  signal(SIGTTOU, SIG_IGN);

>690:

>691:  while (1) {

>692:   if (!jobList.fg) {

>693:    /* на переднем плане нет ни одного задания */

>694:

>695:    /* проверяем, не завершилось выполнение какого-либо фонового задания */

>696:    checkJobs(&jobList);

>697:

>698:    if (!nextCommand) {

>699:     if (getCommand(input, command)) break;

>700:     nextCommand = command;

>701:    }

>702:

>703:    if (!parseCommand(&nextCommand, &newJob, &inBg) &&

>704:     newJob.numProgs) {

>705:     runCommand(newJob, &jobList, inBg);

>706:    }

>707:   } else {

>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;


Рекомендуем почитать
Яйцо кукушки или Преследуя шпиона в компьютерном лабиринте

В отличие от плохого танцора, хорошему сисадмину мешают только кукушкины яйца. Их откладывают в его компьютер злобные хакеры, чтобы из них вылупились программы, делающие своего папу-кукушку суперпользователем. Но сколько кабелю не виться — а кончику быть: бравый сисадмин не дремлет и за годик-другой выводит злоумышленников на чистую воду: на этот раз хакерская тусовка круто пролетела. Такого предельно краткое содержание классической книги эксперта по компьютерной безопасности Клиффа Столла «Яйцо кукушки».


Безопасность информационных систем

В пособии излагаются основные тенденции развития организационного обеспечения безопасности информационных систем, а также подходы к анализу информационной инфраструктуры организационных систем и решению задач обеспечения безопасности компьютерных систем.Для студентов по направлению подготовки 230400 – Информационные системы и технологии (квалификация «бакалавр»).


Руководство по переходу на Ubuntu 10.04 LTS «Lucid Lynx»

Данное руководство по Ubuntu для новичков написано для тех, кто хочет легко и без проблем сменить свою операционную систему на Ubuntu. Оно охватывает вопросы, связанные с установкой, настройкой и использованием Ubuntu.


Сетевые средства Linux

В этой книге описаны принципы действия и область применения многих серверов, выполняющихся в системе Linux. Здесь рассматриваются DHCP-сервер, серверы Samba и NFS, серверы печати, NTP-сервер, средства удаленной регистрации и система X Window. He забыты и средства, традиционно используемые для обеспечения работы Internet-служб: серверы DNS, SMTP, HTTP и FTP. Большое внимание уделено вопросам безопасности сети. В данной книге нашли отражения также средства удаленного администрирования — инструменты Linuxconf, Webmin и SWAT.Данная книга несомненно окажется полезной как начинающим, так и опытным системным администраторам.Отзывы о книге Сетевые средства LinuxПоявилась прекрасная книга по Linux, осталось воспользоваться ею.


Недокументированные и малоизвестные возможности Windows XP

Книга содержит подробные сведения о таких недокументированных или малоизвестных возможностях Windows XP, как принципы работы с программами rundll32.exe и regsvr32.exe, написание скриптов сервера сценариев Windows и создание INF-файлов. В ней приведено описание оснасток, изложены принципы работы с консолью управления mmc.exe и параметрами реестра, которые изменяются с ее помощью. Кроме того, рассмотрено большое количество средств, позволяющих выполнить тонкую настройку Windows XP.Эта книга предназначена для опытных пользователей и администраторов, которым интересно узнать о нестандартных возможностях Windows.


Iptables Tutorial 1.1.19

Iptables Tutorial 1.1.19Автор: (C) Oskar AndreassonCopyright (C) 2001-2002 by Oskar AndreassonПеревод: (C) Андрей КиселевПоследнюю версию документа можно получить по адресу: http://iptables-tutorial.frozentux.netfb2-документ отформатирован с использованием большого количества тегов и . Чтобы в «читалке» (в частности, Haali Reader) текст выглядел «красиво», настройте свойства соотвествующих стилей (emphasis и strong), изменив, например, их цвета или начертания. (прим. автора fb2-документа)