Разработка приложений в среде Linux. Второе издание
Шрифт:
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");
Поделиться с друзьями: