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

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

>368:   strncpy(job->text, *commandPtr, count);

>369:   job->text[count] = '\0';

>370:  }

>371:

>372:  *commandPtr = returnCommand;

>373:

>374:  return 0;

>375: }

>376:

>377: int setupRedirections(struct childProgram * prog) {

>378:  int i;

>379:  int openfd;

>380:  int mode;

>381:  struct redirectionSpecifier * redir = prog->redirections;

>382:

>383:  for (i = 0; i < prog->numRedirections; i++, redir++) {

>384:   switch (redir->type) {

>385:   case REDIRECT_INPUT:

>386:    mode = O_RDONLY;

>387:    break;

>388:   case REDIRECT_OVERWRITE:

>389:    mode = O_RDWR | O_CREAT | O_TRUNC;

>390:    break;

>391:   case REDIRECT_APPEND:

>392:    mode = O_RDWR | O_CREAT | O_APPEND;

>393:    break;

>394:   }

>395:

>396:   openfd = open(redir->filename, mode, 0666);

>397:   if (openfd < 0) {

>398:    /* мы могли потерять это в случае переадресации stderr,

>399:       хотя bash и ash тоже потеряют его (а вот

>400:       zsh - нет!) */

>401:    fprintf(stderr, "ошибка при открытии %s: %s\n",

>402:    redir->filename, strerror(errno));

>403:    return 1;

>404:   }

>405:

>406:   if (openfd != redir->fd) {

>407:    dup2(openfd, redir->fd);

>408:    close(openfd);

>409:   }

>410:  }

>411:

>412:  return 0;

>413: }

>414:

>415: int runCommand(struct job newJob, struct jobSet * jobList,

>416:  int inBg) {

>417:  struct job * job;

>418:  char * newdir, * buf;

>419:  int i, len;

>420:  int nextin, nextout;

>421:  int pipefds[2]; /* pipefd[0] предназначен для чтения */

>422:  char * statusString;

>423:  int jobNum;

>424:  int controlfds[2] ;/*канал для возможности приостановки работы дочернего процесса*/

>425:

>426:  /* здесь производится обработка встраиваемых модулей — мы не используем fork(),

>427:     поэтому, чтобы поместить процесс в фон, придется потрудиться */

>428:  if (!strcmp(newJob.progs[0].argv[0], "exit")) {

>429:   /* здесь возвращается реальный код выхода */

>430:   exit(0);

>431:  } else if (!strcmp(newJob.progs[0].argv[0], "pwd")) {

>432:   len = 50;

>433:   buf = malloc(len);

>434:   while (!getcwd(buf, len) && errno == ERANGE) {

>435:    len += 50;

>436:    buf = realloc(buf, len);

>437:   }

>438:   printf("%s\n", buf);

>439:   free(buf);

>440:   return 0;

>441:  } else if (!strcmp(newJob.progs[0].argv[0], "cd")) {

>442:   if (!newJob.progs[0].argv[1] == 1)

>443:    newdir == getenv("HOME");

>444:   else

>445:    newdir = newJob.progs[0].argv[1];

>446:   if (chdir(newdir))

>447:    printf("сбой при смене текущего каталога: %s\n",

>448:     strerror(errno));

>449:   return 0;

>450:  } else if (!strcmp(newJob.progs[0].argv[0], "jobs")) {

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

>452:    if (job->runningProgs == job->stoppedProgs)

>453:     statusString = "Остановлено";

>454:    else

>455:     statusString = "Выполняется";

>456:

>457:    printf(JOB_STATUS_FORMAT, job->jobId, statusString,

>458:     job->text);

>459:   }

>460:   return 0;

>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[1], "%%%d", &jobNum) != 1) {

>471:    fprintf(stderr, "%s: неверный аргумент '%s'\n",

>472:     newJob.progs[0].argv[0],

>473:     newJob.progs[0].argv[1]);

>474:    return 1;

>475:   }

>476:

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

>478:    if (job->jobId == jobNum) break;

>479:

>480:   if (!job) {

>481:    fprintf(stderr, "%s: неизвестное задание %d\n",

>482:     newJob.progs[0].argv[0], jobNum);

>483:    return 1;

>484:   }

>485:

>486:   if (*new Job. progs[0].argv[0] == 'f') {

>487:    /* Переводим задание на передний план */

>488:

>489:    if (tcsetpgrp(0, job->pgrp))

>490:     perror("tcsetpgrp");

>491:    jobList->fg = job;

>492:   }

>493:

>494:   /* Повторяем запуск процессов в задании */

>495:   for (i = 0; inumProgs; i++)

>496:    job->progs[i].isStopped = 0;

>497:

>498:   kill(-job->pgrp, SIGCONT);

>499:

>500:   job->stoppedProgs = 0;

>501:

>502:   return 0;

>503:  }

>504:

>505:  nextin = 0, nextout = 1;

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

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

>508:    pipe(pipefds);

>509:    nextout = pipefds[1];

>510:   } else {

>511:    nextout = 1;

>512:   }

>513:

>514:   pipe(controlfds);

>515:

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

>517:    signal(SIGTTOU, SIG_DFL);

>518:

>519:    close(controlfds[1]);

>520:    /* при чтении будет возвращен 0, когда записывающая сторона закрыта */

>521:    read(controlfds[0], &len, 1);

>522:    close(controlfds[0]);

>523:

>524:    if (nextin != 0) {

>525:     dup2(nextin, 0);

>526:     close(nextin);

>527:    }

>528:

>529:    if (nextout != 1) {

>530:     dup2(nextout, 1);

>531:     close(nextout);

>532:    }

>533:

>534:    /* явные переадресации подменяют каналы */

>535:    setupRedirections(newJob.progs + i);

>536:

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

>538:    fprintf(stderr, "сбой exec() для %s: %s\n",

>539:    newJob.progs[i].argv[0],

>540:    strerror(errno));

>541:    exit(1);

>542:   }

>543:

>544:   /* помещаем дочерний процесс в группу процессов, лидером в которой

>545:      является первый процесс в этом канале */


Рекомендуем почитать
Виртуальные  машины: несколько компьютеров в  одном

Применение виртуальных машин дает различным категориям пользователей — от начинающих до IT-специалистов — множество преимуществ. Это и повышенная безопасность работы, и простота развертывания новых платформ, и снижение стоимости владения. И потому не случайно сегодня виртуальные машины переживают второе рождение.В книге рассмотрены три наиболее популярных на сегодняшний день инструмента, предназначенных для создания виртуальных машин и управления ими: Virtual PC 2004 компании Microsoft, VMware Workstation от компании VMware и относительно «свежий» продукт — Parallels Workstation, созданный в компании Parallels.


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

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


Windows Vista. Мультимедийный курс

Эта книга поможет вам разобраться в премудростях операционной системы Windows Vista.Информационная насыщенность учебного материала позволяет утверждать, что мультимедийный курс будет интересен и новичкам, и опытным пользователям.


FAQ по смартфону Qtek 8300/8310

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


Домашние и офисные сети под Vista и XP

Количество персональных компьютеров в нашей стране растет год от года. Сегодня во многих семьях имеется два или даже три компьютера.Чтобы воспользоваться всеми преимуществами такой ситуации, компьютеры в вашей квартире стоит объединить сетью. Это позволит вам играть по сети в компьютерные игры, совместно использовать дисковое пространство, принтеры, модемы и другие устройства, всю сеть можно соединить с Интернетом. А в офисах сеть между компьютерами просто необходима.Открывающиеся перспективы выглядят очень заманчиво.


Свободные программы и системы в школе

Курс лекций, включенных в брошюру, знакомит читателя с популярными свободными программами и системами, полезными при преподавании информатики в средней школе. В обзор вошли основы открытых операционных систем, сведения о пакете «офисных» программ OpenOffice.org, коммуникационном пакете Mozilla, графическом редакторе GIMP, современных графических средах GNOME и KDE и других программах.Для преподавателей информатики и методистов, а также для студентов и аспирантов соответствующих специальностей.© 2002-3, Максим Отставнов.© 2002, Андрей Добровольский (раздел 3.1).Использован текст лекций, публиковавшихся автором в приложении к газете «Первое сентября» «Информатика» (http://inf.1september.ru) в 2002-3 г., материалы брошюры «Прикладные свободные программы в школе» (М.: 2003 г.), а также фрагменты статей, ранее публиковавшихся в журналах «Компьютерра» и «Домашний компьютер».Материалы, представленные в этой книге, также доступны в Интернет на странице www.otstavnov.com/fsft на условиях Свободной лицензии ГНУ на документацию (GNU FDL)