99: flags = GLOB_APPEND;
100: i = prog->globResult.gl_pathc;
101: } else {
102: prog->freeGlob = 1;
103: flags = 0;
104: i = 0;
105: }
106:
107: rc = glob(prog->argv[argc - 1], flags, NULL, &prog->globResult);
108: if (rc == GLOB_NOSPACE) {
109: fprintf(stderr, 'недостаточно пространства для универсализации
');
110: return;
111: } else if (rc == GLOB_NOMATCH ||
112: (!rc && (prog->globResult.gl_pathc - i) == 1 &&
113: !strcmp(prog->argv[argc - 1],
114: prog->globResult.gl_pathv[i]))) {
115: /* нам нужно удалить все, что до сих пор было заключено между */
116: src = dst = prog->argv[argc - 1];
117: while (*src) {
118: if (*src != '\') *dst++ = *src;
119: src++;
120: }
121: *dst = ' ';
122: } else if (!rc) {
123: argcAlloced += (prog->globResult.gl_pathc - i);
124: prog->argv = realloc(prog->argv,
125: argcAlloced * sizeof(*prog->argv));
126: memcpy(prog->argv + (argc - 1),
127: prog->globResult.gl_pathv + i,
128: sizeof(*(prog->argv)) *
129: (prog->globResult.gl_pathc - i));
130: argc += (prog->globResult.gl_pathc - i - 1);
131: }
132:
133: *argcAllocedPtr = argcAlloced;
134: *argcPtr = argc;
135: }
136:
137: /* Возвращаем cmd->numProgs как 0, если не представлено ни одной команды
138: (например, пустая строка). Если будет обнаружена допустимая команда,
139: commandPtr будет ссылаться на начало следующей команды (если исходная
140: команда была связана с несколькими заданиями) или будет равно NULL,
141: если больше не представлено ни одной команды. */
142: int parseCommand(char ** commandPtr, struct job * job, int * isBg) {
143: char * command;
144: char * returnCommand = NULL;
145: char * src, * buf, * chptr;
146: int argc = 0;
147: int done = 0;
148: int argvAlloced;
149: int i;
150: char quote = ' ';
151: int count;
152: struct childProgram * prog;
153:
154: /* пропускаем первое свободное место (например, пробел) */
155: while (**commandPtr && isspace(**commandPtr)) (*commandPtr)+ +;
156:
157: /* обрабатываем пустые строки и первые символы '#' */
158: if (!**commandPtr || (**commandPtr=='#')) {
159: job->numProgs = 0;
160: *commandPtr = NULL;
161: return 0;
162: }
163:
164: *isBg = 0;
165: job->numProgs = 1;
166: job->progs = malloc(sizeof(*job->progs));
167:
168: /* Мы задаем элементы массива argv для ссылки внутри строки.
169: Освобождение памяти осуществляется с помощью функции freeJob().
170:
171: Получив незанятую память, нам не нужно будет использовать завершающие
172: значения NULL, поэтому оставшаяся часть будет выглядеть аккуратнее
173: (хотя, честно говоря, менее эффективно). */
174: job->cmdBuf = command = calloc(1, strlen(*commandPtr) + 1);
175: job->text = NULL;
176:
177: prog = job->progs;
178: prog->numRedirections = 0;
179: prog->redirections = NULL;
180: prog->freeGlob = 0;
181: prog->isStopped = 0;
182:
183: argvAlloced = 5;
184: prog->argv = malloc(sizeof(*prog->argv) * argvAlloced);
185: prog->argv[0] = job->cmdBuf;
186:
187: buf = command;
188: src = *commandPtr;
189: while (*src && !done) {
190: if (quote == *src) {
191: quote = ' ';
192: } else if (quote) {
193: if (*src ==0 '\') {