329: returnCommand = *commandPtr + (src - * commandPtr) + 1;
330: break;
331:
332: case '\\':
333: src++;
334: if (!*src) {
335: freeJob(job);
336: fprintf(stderr, "после \\ ожидался символ\n");
337: return 1;
338: }
339: if (*src == '*' | | *src == '[' || *src == '] '
340: || *src == '?')
341: *buf++ = '\\';
342: /* неудача */
343: default:
344: *buf++ = *src;
345: }
346:
347: src++;
348: }
349:
350: if (*prog->argv[argc]) {
351: argc++;
352: globLastArgument(prog, &argc, &argvAlloced);
353: }
354: if (!argc) {
355: freeJob(job);
356: return 0;
357: }
358: prog->argv[argc] = NULL;
359:
360: if (!returnCommand) {
361: job->text = malloc(strlen(*commandPtr) + 1);
362: strcpy(job->text, *commandPtr);
363: } else {
364: /*Оставляем любые хвостовые пробелы, хотя и получится это несколько небрежно*/
365:
366: count = returnCommand - *commandPtr;
367: job->text = malloc(count + 1);
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: