104: i = 0;
105: }
106:
107: rc = glob(prog->argv[argc - 1], flags, NULL, &prog->globResult);
108: if (rc == GLOB_NOSPACE) {
109: fprintf(stderr, "Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π° Π΄Π»Ρ ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ\n");
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 = '\0';
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 = '\0';
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 = '\0';
192: } else if (quote) {
193: if (*src ==0 '\\') {
194: src++;
195: if (!*src) {
196: fprintf(stderr,
197: "ΠΏΠΎΡΠ»Π΅ \\ ΠΎΠΆΠΈΠ΄Π°Π»ΡΡ ΡΠΈΠΌΠ²ΠΎΠ»\n");
198: freeJob(job);
199: return 1;
200: }
201:
202: /* Π² ΠΎΠ±ΠΎΠ»ΠΎΡΠΊΠ΅ ΡΠΎΡΠ΅ΡΠ°Π½ΠΈΠ΅ "\'" Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π΄Π°ΡΡ */
203: if (*src != quote) *buf++ = '\\';
204: } else if (*src == '*' | | *src == ' ?' | | *src == '[' ||
205: *src == ']')
206: *buf++ = '\\';
207: *buf++ = *src;
208: } else if (isspace(*src)) {
209: if (*prog->argv[argc]) {
210: buf++, argc++;
211: /* +1 Π·Π΄Π΅ΡΡ ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΌΠ΅ΡΡΠΎ Π΄Π»Ρ NULL, ΠΊΠΎΡΠΎΡΠΎΠ΅
212: Π·Π°Π²Π΅ΡΡΠ°Π΅Ρ ΠΌΠ°ΡΡΠΈΠ² argv */
213: if ((argc + 1) == argvAlloced) {
214: argvAlloced += 5;
215: prog->argv = realloc(prog->argv,
216: sizeof(*prog->argv) * argvAlloced);
217: }
218: prog->argv[argc] = buf;
219:
220: globLastArgument(prog, &argc, &argvAlloced);
221: }
222: } else switch (*src) {
223: case '"':
224: case '\'':
225: quote = *src;
226: break;
227:
228: case '#': /* ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΉ */
229: done = 1;
230: break;
231:
232: case '>': /* ΠΏΠ΅ΡΠ΅Π°Π΄ΡΠ΅ΡΠ°ΡΠΈΠΈ */
233: case '<':
234: i = prog->numRedirections++;
235: prog->redirections = realloc(prog->redirections,
236: sizeof(*prog->redirections) * (i+1));
237:
238: prog->redirections[i].fd= -1;
239: if (buf != prog->argv[argc]) {
240: /* ΠΏΠ΅ΡΠ΅Π΄ ΡΡΠΈΠΌ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠΌ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠΊΠ°Π·Π°Π½ Π½ΠΎΠΌΠ΅Ρ
241: ΠΏΠ΅ΡΠ΅Π°Π΄ΡΠ΅ΡΠΎΠ²ΡΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° */
242: prog->redirections[i].fd =
243: strtol(prog->argv[argc], &chptr, 10);
244:
245: if (*chptr && *prog->argv[argc]) {
246: buf++, argc++;
247: globLastArgument(prog, &argc, &argvAlloced);
248: }
249: }
250:
251: if (prog->redirections[i].fd == -1) {
252: if (*src == '>')
253: prog->redirections[i].fd = 1;
254: else
255: prog->redirections[i].fd = 0;
256: }
257:
258: if (*src++ == '>') {
259: if (*src == '>') {
260: prog->redirections[i].type = REDIRECT_APPEND;
261: src++;
262: } else {
263: prog->redirections[i].type = REDIRECT_OVERWRIΠ’Π;
264: }
265: } else {
266: prog->redirections[i].type = REDIRECT_INPUT;
267: }
268:
269: /* ΠΡΠΎ Π½Π΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ ΡΡΠ°Π½Π΄Π°ΡΡΡ sh POSIX. ΠΡ ΠΈ Π»Π°Π΄Π½ΠΎ. */
270: chptr = src;
271: while (isspace(*chptr)) chptr++;
272:
273: if (!*chptr) {
274: fprintf(stderr, "ΠΏΠΎΡΠ»Π΅ %c ΠΎΠΆΠΈΠ΄Π°Π»ΠΎΡΡ ΠΈΠΌΡ ΡΠ°ΠΉΠ»Π°\n",
275: *src);
276: freeJob(job);
277: return 1;
278: }
279:
280: prog->redirections[i].filename = buf;
281: while (*chptr && !isspace(*chptr))
282: *buf++ = *chptr++;
283:
284: src = chptr - 1; /* src++ Π±ΡΠ΄Π΅Ρ ΡΠ΄Π΅Π»Π°Π½ΠΎ ΠΏΠΎΠ·ΠΆΠ΅ */
285: prog->argv[argc] = ++buf;
286: break;
287:
288: case '|': /* ΠΊΠ°Π½Π°Π» */
289: /* Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠ΅ ΡΡΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ */
290: if (*prog->argv[argc]) argc++;
291: if (large) {
292: fprintf(stderr, "ΠΏΡΡΡΠ°Ρ ΠΊΠΎΠΌΠ°Π½Π΄Π° Π² ΠΊΠ°Π½Π°Π»Π΅\n");
293: freeJob(job);
294: return 1;
295: }
296: prog->argv[argc] = NULL;
297:
298: /* ΠΈ Π½Π°ΡΠ°Π»ΠΎ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ */
299: job->numProgs++;
300: job->progs = realloc(job->progs,
301: sizeof (*job->progs) *
302: job->numProgs);
303: prog = job->progs + (job->numProgs - 1);
304: prog->numRedirections = 0;
305: prog->redirections = NULL;
306: prog->freeGlob = 0;
307: argc = 0;
308:
309: argvAlloced = 5;
310: prog->argv = malloc(sizeof(*prog->argv) *
311: argvAlloced);
312: prog->argv[0] = ++buf;
313:
314: src++;
315: while (*src && isspace(*src)) src++;
316:
317: if (!*src) {
318: fprintf(stderr, "ΠΏΡΡΡΠ°Ρ ΠΊΠΎΠΌΠ°Π½Π΄Π° Π² ΠΊΠ°Π½Π°Π»Π΅\n");
319: return 1;
320: }
321: src--; /* ΠΈΠ½ΠΊΡΠ΅ΠΌΠ΅Π½Ρ ++ ΠΌΡ ΡΠ΄Π΅Π»Π°Π΅ΠΌ Π² ΠΊΠΎΠ½ΡΠ΅ ΡΠΈΠΊΠ»Π° */
322:
323: break;
324:
325: case '&': /* ΡΠΎΠ½ */
326: *isBg = 1;
327: case ';': /* ΡΠ°Π·Π½ΠΎΠΎΠ±ΡΠ°Π·Π½ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ */
328: done = 1;
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);