Разработка приложений в среде 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;
Одно из немногих изданий на русском языке, которое посвящено старейшей глобальной компьютерной сети "Fidonet". Сатирический справочник о жизни и смерти самого древнего сетевого сообщества, которое до сих пор существует среди нас.
В пособии излагаются основные тенденции развития организационного обеспечения безопасности информационных систем, а также подходы к анализу информационной инфраструктуры организационных систем и решению задач обеспечения безопасности компьютерных систем.Для студентов по направлению подготовки 230400 – Информационные системы и технологии (квалификация «бакалавр»).
В книге американских авторов — разработчиков операционной системы UNIX — блестяще решена проблема автоматизации деятельности программиста, системной поддержки его творчества, выходящей за рамки языков программирования. Профессионалам открыт богатый "встроенный" арсенал системы UNIX. Многочисленными примерами иллюстрировано использование языка управления заданиями shell.Для программистов-пользователей операционной системы UNIX.
Книга адресована программистам, работающим в самых разнообразных ОС UNIX. Авторы предлагают шире взглянуть на возможности параллельной организации вычислительного процесса в традиционном программировании. Особый акцент делается на потоках (threads), а именно на тех возможностях и сложностях, которые были привнесены в технику параллельных вычислений этой относительно новой парадигмой программирования. На примерах реальных кодов показываются приемы и преимущества параллельной организации вычислительного процесса.
Применение виртуальных машин дает различным категориям пользователей — от начинающих до IT-специалистов — множество преимуществ. Это и повышенная безопасность работы, и простота развертывания новых платформ, и снижение стоимости владения. И потому не случайно сегодня виртуальные машины переживают второе рождение.В книге рассмотрены три наиболее популярных на сегодняшний день инструмента, предназначенных для создания виртуальных машин и управления ими: Virtual PC 2004 компании Microsoft, VMware Workstation от компании VMware и относительно «свежий» продукт — Parallels Workstation, созданный в компании Parallels.
Книга содержит подробные сведения о таких недокументированных или малоизвестных возможностях Windows XP, как принципы работы с программами rundll32.exe и regsvr32.exe, написание скриптов сервера сценариев Windows и создание INF-файлов. В ней приведено описание оснасток, изложены принципы работы с консолью управления mmc.exe и параметрами реестра, которые изменяются с ее помощью. Кроме того, рассмотрено большое количество средств, позволяющих выполнить тонкую настройку Windows XP.Эта книга предназначена для опытных пользователей и администраторов, которым интересно узнать о нестандартных возможностях Windows.