585:
586: printf('[%d] %d
', 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: '<команды>
');
678: exit(1);
679: } else if (argc == 2) {
680: input = fopen(argv[1], 'r');
681: if (!input) {
682: perror('fopen');