212: printf(JOB_STATUS_FORMAT, job->jobId, "Работаю",
213: job->text);
214: return 0;
215: }
216:
217: /* у нас пока только одна программа на дочернее задание,
218: потому это просто */
219: if (!(newJob.progs[0].pid = fork())) {
220: execvp(newJob.progs[0].argv[0],newJob.progs[0].argv);
221: fprintf(stderr, "exec() для %s потерпела неудачу: %s\n",
222: newJob.progs[0].argv[0],
223: strerror(errno));
224: exit(1);
225: }
226:
227: /* поместить дочернюю программу в отдельную группу процессов */
228: setpgid(newJob.progs[0].pid,newJob.progs[0].pid);
229:
230: newJob.pgrp = newJob.progs[0].pid;
231:
232: /* найти идентификатор для задания */
233: newJob.jobld = 1;
234: for (job = jobList->head; job; job = job->next)
235: if (job->jobId >= newJob.jobId)
236: newJob.jobId = job->jobId+1;
237:
238: /* задание для списка заданий */
239: if (!jobList->head) {
240: job = jobList->head = malloc(sizeof(*job));
241: } else {
242: for (job = jobList->head; job->next; job = job->next);
243: job->next = malloc(sizeof(*job));
244: job = job->next;
245: }
246:
247: *job = newJob;
248: job->next = NULL;
249: job->runningProgs = job->numProgs;
250:
251: if (inBg) {
252: /* мы не ждем завершения фоновых заданий - добавить
253: в список фоновых заданий и оставить в покое */
254:
255: printf("[%d]%d\n", job->jobId,
256: newJob.progs[newJob.numProgs-1].pid);
257: } else {
258: jobList->fg=job;
259:
260: /* переместить новую группу процессов на передний план */
261:
262: if (tcsetpgrp(0,newJob.pgrp))
263: perror("tcsetpgrp");
264: }
265:
266: return 0;
267: }
268:
269: void removeJob(struct jobSet *jobList, struct job *job) {
270: struct job *prevJob;
271:
272: freeJob(job);
273: if (job == jobList->head) {
274: jobList->head=job->next;
275: } else {
276: prevJob = jobList->head;
277: while (prevJob->next != job) prevJob = prevJob->next;
278: prevJob->next=job->next;
279: }
280:
281: free(job);
282: }
283:
284: /* Проверить, завершился ли какой-то из фоновых процессов -
285: если да, выяснить, почему и определить, завершилось ли задание */
286: void checkJobs(struct jobSet *jobList) {
287: struct job *job;
288: pid_t childpid;
289: int status;
290: int progNum;
291:
292: while ((childpid = waitpid(-1, &status, WNOHANG))>0) {
293: for (job = jobList->head;job;job = job->next) {
294: progNum = 0;
295: while (progNum
296: job->progs[progNum].pid != childpid)
297: progNum++;
298: if (progNum
299: }
300: