3: #define _GNU_SOURCE

  4:

  5: #include <ctype.h>

  6: #include <errno.h>

  7: #include <fcntl.h>

  8: #include <glob.h>

  9: #include <signal.h>

 10: #include <stdio.h>

 11: #include <stdlib.h>

 12: #include <string.h>

 13: #include <sys/ioctl.h>

 14: #include <sys/wait.h>

 15: #include <unistd.h>

 16:

 17: #define MAX_COMMAND_LEN 250 /* максимальная длина одной

 18:                                командной строки */

 19: #define JOB_STATUS_FORMAT '[%d] %-22s %.40s '

 20:

 21: struct jobSet {

 22:  struct job * head; /* заголовок списка выполняющихся заданий */

 23:  struct job * fg; /* текущее высокоприоритетное задание */

 24: };

 25:

 26: enum redirectionType { REDIRECT_INPUT, REDIRECT_OVERWRITE,

 27:                        REDIRECT_APPEND };

 28:

 29: struct redirectionSpecifier {

 30:  enum redirectionType type; /* тип переадресации */

 31:  int fd;                    /* переадресация fd */

 32:  char * filename;           /* файл, в который будет переадресовано fd */

 33: };

 34:

 35: struct childProgram {

 36:  pid_t pid;                                 /* 0 в случае выхода */

 37:  char ** argv;                              /* имя программы и аргументы */

 38:  int numRedirections;                       /* элементы в массиве переадресации */

 39:  struct redirectionSpecifier* redirections; /* переадресации ввода-вывода */

 40:  glob_t globResult;                         /* результат универсализации параметра */

 41:  int freeGlob;                              /* нужно ли освобождать globResult? */

 42:  int isStopped;                             /* выполняется ли в данный момент программа? */

 43: };

 44:

 45: struct job {

 46:  int jobId;        /* номер задания */

 47:  int numProgs;     /* количество программ в задании */

 48:  int runningProgs; /* количество выполняющихся программ */

 49:  char * text;      /* имя задания */

 50:  char * cmdBuf;    /* буфер, на который ссылаются различные массивы argv */

 51:  pid_t pgrp;       /* идентификатор группы процесса для задания */

 52:  struct childProgram* progs; /* массив программ в задании */

 53:  struct job* next; /* для отслеживания фоновых команд */

 54:  int stoppedProgs; /* количество активных, но приостановленных программ */

 55: };

 56:

 57: void freeJob (struct job * cmd) {

 58:  int i;

 59:

 60:  for (i = 0; i <cmd->numProgs; i++) {

 61:   free(cmd->progs[i].argv);

 62:   if (cmd->progs[i].redirections)

 63:    free(cmd->progs[i].redirections);

 64:   if (cmd->progs[i].freeGlob)

 65:    globfree(&cmd->progs[i].globResult);

 66:  }

 67:  free(cmd->progs);

 68:  if (cmd->text) free(cmd->text);

 69:   free(cmd->cmdBuf);

 70: }

 71:

 72: int getCommand(FILE * source, char * command) {

 73:  if (source == stdin) {

 74:   printf('# ');

 75:   fflush(stdout);

 76:  }

 77:

 78:  if (!fgets(command, MAX_COMMAND_LEN, source)) {

 79:   if (source == stdin) printf(' ');

 80:   return 1;

 81:  }

 82:

 83:  /* удаление хвостового символа новой строки */

 84:  command[strlen(command) - 1] = '';

 85:

 86:  return 0;

 87: }

 88:

 89: void globLastArgument(struct childProgram * prog, int * argcPtr,

 90:  int * argcAllocedPtr) {

 91:  int argc = *argcPtr;

 92:  int argcAlloced = *argcAllocedPtr;

 93:  int rc;

 94:  int flags;

 95:  int i;

 96:  char * src, * dst;

 98:  if (argc>1) { /* cmd->globResult уже инициализирован */

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату