]> git.ipfire.org Git - thirdparty/bash.git/blob - make_cmd.c
Bash-5.2 patch 26: fix typo when specifying readline's custom color prefix
[thirdparty/bash.git] / make_cmd.c
1 /* make_cmd.c -- Functions for making instances of the various
2 parser constructs. */
3
4 /* Copyright (C) 1989-2018 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #include <stdio.h>
25 #include "bashtypes.h"
26 #if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
27 # include <sys/file.h>
28 #endif
29 #include "filecntl.h"
30 #include "bashansi.h"
31 #if defined (HAVE_UNISTD_H)
32 # include <unistd.h>
33 #endif
34
35 #include "bashintl.h"
36
37 #include "shell.h"
38 #include "execute_cmd.h"
39 #include "parser.h"
40 #include "flags.h"
41 #include "input.h"
42
43 #if defined (JOB_CONTROL)
44 #include "jobs.h"
45 #endif
46
47 #include "shmbutil.h"
48
49 int here_doc_first_line = 0;
50
51 /* Object caching */
52 sh_obj_cache_t wdcache = {0, 0, 0};
53 sh_obj_cache_t wlcache = {0, 0, 0};
54
55 #define WDCACHESIZE 128
56 #define WLCACHESIZE 128
57
58 static COMMAND *make_for_or_select __P((enum command_type, WORD_DESC *, WORD_LIST *, COMMAND *, int));
59 #if defined (ARITH_FOR_COMMAND)
60 static WORD_LIST *make_arith_for_expr __P((char *));
61 #endif
62 static COMMAND *make_until_or_while __P((enum command_type, COMMAND *, COMMAND *));
63
64 void
65 cmd_init ()
66 {
67 ocache_create (wdcache, WORD_DESC, WDCACHESIZE);
68 ocache_create (wlcache, WORD_LIST, WLCACHESIZE);
69 }
70
71 WORD_DESC *
72 alloc_word_desc ()
73 {
74 WORD_DESC *temp;
75
76 ocache_alloc (wdcache, WORD_DESC, temp);
77 temp->flags = 0;
78 temp->word = 0;
79 return temp;
80 }
81
82 WORD_DESC *
83 make_bare_word (string)
84 const char *string;
85 {
86 WORD_DESC *temp;
87
88 temp = alloc_word_desc ();
89
90 if (*string)
91 temp->word = savestring (string);
92 else
93 {
94 temp->word = (char *)xmalloc (1);
95 temp->word[0] = '\0';
96 }
97
98 return (temp);
99 }
100
101 WORD_DESC *
102 make_word_flags (w, string)
103 WORD_DESC *w;
104 const char *string;
105 {
106 register int i;
107 size_t slen;
108 DECLARE_MBSTATE;
109
110 i = 0;
111 slen = strlen (string);
112 while (i < slen)
113 {
114 switch (string[i])
115 {
116 case '$':
117 w->flags |= W_HASDOLLAR;
118 break;
119 case '\\':
120 break; /* continue the loop */
121 case '\'':
122 case '`':
123 case '"':
124 w->flags |= W_QUOTED;
125 break;
126 }
127
128 ADVANCE_CHAR (string, slen, i);
129 }
130
131 return (w);
132 }
133
134 WORD_DESC *
135 make_word (string)
136 const char *string;
137 {
138 WORD_DESC *temp;
139
140 temp = make_bare_word (string);
141 return (make_word_flags (temp, string));
142 }
143
144 WORD_DESC *
145 make_word_from_token (token)
146 int token;
147 {
148 char tokenizer[2];
149
150 tokenizer[0] = token;
151 tokenizer[1] = '\0';
152
153 return (make_word (tokenizer));
154 }
155
156 WORD_LIST *
157 make_word_list (word, wlink)
158 WORD_DESC *word;
159 WORD_LIST *wlink;
160 {
161 WORD_LIST *temp;
162
163 ocache_alloc (wlcache, WORD_LIST, temp);
164
165 temp->word = word;
166 temp->next = wlink;
167 return (temp);
168 }
169
170 COMMAND *
171 make_command (type, pointer)
172 enum command_type type;
173 SIMPLE_COM *pointer;
174 {
175 COMMAND *temp;
176
177 temp = (COMMAND *)xmalloc (sizeof (COMMAND));
178 temp->type = type;
179 temp->value.Simple = pointer;
180 temp->value.Simple->flags = temp->flags = 0;
181 temp->redirects = (REDIRECT *)NULL;
182 return (temp);
183 }
184
185 COMMAND *
186 command_connect (com1, com2, connector)
187 COMMAND *com1, *com2;
188 int connector;
189 {
190 CONNECTION *temp;
191
192 temp = (CONNECTION *)xmalloc (sizeof (CONNECTION));
193 temp->connector = connector;
194 temp->first = com1;
195 temp->second = com2;
196 return (make_command (cm_connection, (SIMPLE_COM *)temp));
197 }
198
199 static COMMAND *
200 make_for_or_select (type, name, map_list, action, lineno)
201 enum command_type type;
202 WORD_DESC *name;
203 WORD_LIST *map_list;
204 COMMAND *action;
205 int lineno;
206 {
207 FOR_COM *temp;
208
209 temp = (FOR_COM *)xmalloc (sizeof (FOR_COM));
210 temp->flags = 0;
211 temp->name = name;
212 temp->line = lineno;
213 temp->map_list = map_list;
214 temp->action = action;
215 return (make_command (type, (SIMPLE_COM *)temp));
216 }
217
218 COMMAND *
219 make_for_command (name, map_list, action, lineno)
220 WORD_DESC *name;
221 WORD_LIST *map_list;
222 COMMAND *action;
223 int lineno;
224 {
225 return (make_for_or_select (cm_for, name, map_list, action, lineno));
226 }
227
228 COMMAND *
229 make_select_command (name, map_list, action, lineno)
230 WORD_DESC *name;
231 WORD_LIST *map_list;
232 COMMAND *action;
233 int lineno;
234 {
235 #if defined (SELECT_COMMAND)
236 return (make_for_or_select (cm_select, name, map_list, action, lineno));
237 #else
238 last_command_exit_value = 2;
239 return ((COMMAND *)NULL);
240 #endif
241 }
242
243 #if defined (ARITH_FOR_COMMAND)
244 static WORD_LIST *
245 make_arith_for_expr (s)
246 char *s;
247 {
248 WORD_LIST *result;
249 WORD_DESC *wd;
250
251 if (s == 0 || *s == '\0')
252 return ((WORD_LIST *)NULL);
253 wd = make_word (s);
254 wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_DQUOTE; /* no word splitting or globbing */
255 #if defined (PROCESS_SUBSTITUTION)
256 wd->flags |= W_NOPROCSUB; /* no process substitution */
257 #endif
258 result = make_word_list (wd, (WORD_LIST *)NULL);
259 return result;
260 }
261 #endif
262
263 /* Note that this function calls dispose_words on EXPRS, since it doesn't
264 use the word list directly. We free it here rather than at the caller
265 because no other function in this file requires that the caller free
266 any arguments. */
267 COMMAND *
268 make_arith_for_command (exprs, action, lineno)
269 WORD_LIST *exprs;
270 COMMAND *action;
271 int lineno;
272 {
273 #if defined (ARITH_FOR_COMMAND)
274 ARITH_FOR_COM *temp;
275 WORD_LIST *init, *test, *step;
276 char *s, *t, *start;
277 int nsemi, i;
278
279 init = test = step = (WORD_LIST *)NULL;
280 /* Parse the string into the three component sub-expressions. */
281 start = t = s = exprs->word->word;
282 for (nsemi = 0; ;)
283 {
284 /* skip whitespace at the start of each sub-expression. */
285 while (whitespace (*s))
286 s++;
287 start = s;
288 /* skip to the semicolon or EOS */
289 i = skip_to_delim (start, 0, ";", SD_NOJMP|SD_NOPROCSUB);
290 s = start + i;
291
292 t = (i > 0) ? substring (start, 0, i) : (char *)NULL;
293
294 nsemi++;
295 switch (nsemi)
296 {
297 case 1:
298 init = make_arith_for_expr (t);
299 break;
300 case 2:
301 test = make_arith_for_expr (t);
302 break;
303 case 3:
304 step = make_arith_for_expr (t);
305 break;
306 }
307
308 FREE (t);
309 if (*s == '\0')
310 break;
311 s++; /* skip over semicolon */
312 }
313
314 if (nsemi != 3)
315 {
316 if (nsemi < 3)
317 parser_error (lineno, _("syntax error: arithmetic expression required"));
318 else
319 parser_error (lineno, _("syntax error: `;' unexpected"));
320 parser_error (lineno, _("syntax error: `((%s))'"), exprs->word->word);
321 free (init);
322 free (test);
323 free (step);
324 last_command_exit_value = 2;
325 return ((COMMAND *)NULL);
326 }
327
328 temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
329 temp->flags = 0;
330 temp->line = lineno;
331 temp->init = init ? init : make_arith_for_expr ("1");
332 temp->test = test ? test : make_arith_for_expr ("1");
333 temp->step = step ? step : make_arith_for_expr ("1");
334 temp->action = action;
335
336 dispose_words (exprs);
337 return (make_command (cm_arith_for, (SIMPLE_COM *)temp));
338 #else
339 dispose_words (exprs);
340 last_command_exit_value = 2;
341 return ((COMMAND *)NULL);
342 #endif /* ARITH_FOR_COMMAND */
343 }
344
345 COMMAND *
346 make_group_command (command)
347 COMMAND *command;
348 {
349 GROUP_COM *temp;
350
351 temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
352 temp->command = command;
353 return (make_command (cm_group, (SIMPLE_COM *)temp));
354 }
355
356 COMMAND *
357 make_case_command (word, clauses, lineno)
358 WORD_DESC *word;
359 PATTERN_LIST *clauses;
360 int lineno;
361 {
362 CASE_COM *temp;
363
364 temp = (CASE_COM *)xmalloc (sizeof (CASE_COM));
365 temp->flags = 0;
366 temp->line = lineno;
367 temp->word = word;
368 temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *);
369 return (make_command (cm_case, (SIMPLE_COM *)temp));
370 }
371
372 PATTERN_LIST *
373 make_pattern_list (patterns, action)
374 WORD_LIST *patterns;
375 COMMAND *action;
376 {
377 PATTERN_LIST *temp;
378
379 temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
380 temp->patterns = REVERSE_LIST (patterns, WORD_LIST *);
381 temp->action = action;
382 temp->next = NULL;
383 temp->flags = 0;
384 return (temp);
385 }
386
387 COMMAND *
388 make_if_command (test, true_case, false_case)
389 COMMAND *test, *true_case, *false_case;
390 {
391 IF_COM *temp;
392
393 temp = (IF_COM *)xmalloc (sizeof (IF_COM));
394 temp->flags = 0;
395 temp->test = test;
396 temp->true_case = true_case;
397 temp->false_case = false_case;
398 return (make_command (cm_if, (SIMPLE_COM *)temp));
399 }
400
401 static COMMAND *
402 make_until_or_while (which, test, action)
403 enum command_type which;
404 COMMAND *test, *action;
405 {
406 WHILE_COM *temp;
407
408 temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
409 temp->flags = 0;
410 temp->test = test;
411 temp->action = action;
412 return (make_command (which, (SIMPLE_COM *)temp));
413 }
414
415 COMMAND *
416 make_while_command (test, action)
417 COMMAND *test, *action;
418 {
419 return (make_until_or_while (cm_while, test, action));
420 }
421
422 COMMAND *
423 make_until_command (test, action)
424 COMMAND *test, *action;
425 {
426 return (make_until_or_while (cm_until, test, action));
427 }
428
429 COMMAND *
430 make_arith_command (exp)
431 WORD_LIST *exp;
432 {
433 #if defined (DPAREN_ARITHMETIC)
434 COMMAND *command;
435 ARITH_COM *temp;
436
437 command = (COMMAND *)xmalloc (sizeof (COMMAND));
438 command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
439
440 temp->flags = 0;
441 temp->line = line_number;
442 temp->exp = exp;
443
444 command->type = cm_arith;
445 command->redirects = (REDIRECT *)NULL;
446 command->flags = 0;
447
448 return (command);
449 #else
450 last_command_exit_value = 2;
451 return ((COMMAND *)NULL);
452 #endif
453 }
454
455 #if defined (COND_COMMAND)
456 struct cond_com *
457 make_cond_node (type, op, left, right)
458 int type;
459 WORD_DESC *op;
460 struct cond_com *left, *right;
461 {
462 COND_COM *temp;
463
464 temp = (COND_COM *)xmalloc (sizeof (COND_COM));
465 temp->flags = 0;
466 temp->line = line_number;
467 temp->type = type;
468 temp->op = op;
469 temp->left = left;
470 temp->right = right;
471
472 return (temp);
473 }
474 #endif
475
476 COMMAND *
477 make_cond_command (cond_node)
478 COND_COM *cond_node;
479 {
480 #if defined (COND_COMMAND)
481 COMMAND *command;
482
483 command = (COMMAND *)xmalloc (sizeof (COMMAND));
484 command->value.Cond = cond_node;
485
486 command->type = cm_cond;
487 command->redirects = (REDIRECT *)NULL;
488 command->flags = 0;
489 command->line = cond_node ? cond_node->line : 0;
490
491 return (command);
492 #else
493 last_command_exit_value = 2;
494 return ((COMMAND *)NULL);
495 #endif
496 }
497
498 COMMAND *
499 make_bare_simple_command ()
500 {
501 COMMAND *command;
502 SIMPLE_COM *temp;
503
504 command = (COMMAND *)xmalloc (sizeof (COMMAND));
505 command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
506
507 temp->flags = 0;
508 temp->line = line_number;
509 temp->words = (WORD_LIST *)NULL;
510 temp->redirects = (REDIRECT *)NULL;
511
512 command->type = cm_simple;
513 command->redirects = (REDIRECT *)NULL;
514 command->flags = 0;
515
516 return (command);
517 }
518
519 /* Return a command which is the connection of the word or redirection
520 in ELEMENT, and the command * or NULL in COMMAND. */
521 COMMAND *
522 make_simple_command (element, command)
523 ELEMENT element;
524 COMMAND *command;
525 {
526 /* If we are starting from scratch, then make the initial command
527 structure. Also note that we have to fill in all the slots, since
528 malloc doesn't return zeroed space. */
529 if (command == 0)
530 {
531 command = make_bare_simple_command ();
532 parser_state |= PST_REDIRLIST;
533 }
534
535 if (element.word)
536 {
537 command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
538 parser_state &= ~PST_REDIRLIST;
539 }
540 else if (element.redirect)
541 {
542 REDIRECT *r = element.redirect;
543 /* Due to the way <> is implemented, there may be more than a single
544 redirection in element.redirect. We just follow the chain as far
545 as it goes, and hook onto the end. */
546 while (r->next)
547 r = r->next;
548 r->next = command->value.Simple->redirects;
549 command->value.Simple->redirects = element.redirect;
550 }
551
552 return (command);
553 }
554
555 /* Because we are Bourne compatible, we read the input for this
556 << or <<- redirection now, from wherever input is coming from.
557 We store the input read into a WORD_DESC. Replace the text of
558 the redirectee.word with the new input text. If <<- is on,
559 then remove leading TABS from each line. */
560 void
561 make_here_document (temp, lineno)
562 REDIRECT *temp;
563 int lineno;
564 {
565 int kill_leading, redir_len;
566 char *redir_word, *document, *full_line;
567 int document_index, document_size, delim_unquoted;
568
569 if (temp->instruction != r_deblank_reading_until &&
570 temp->instruction != r_reading_until)
571 {
572 internal_error (_("make_here_document: bad instruction type %d"), temp->instruction);
573 return;
574 }
575
576 kill_leading = temp->instruction == r_deblank_reading_until;
577
578 document = (char *)NULL;
579 document_index = document_size = 0;
580
581 /* Quote removal is the only expansion performed on the delimiter
582 for here documents, making it an extremely special case. */
583 redir_word = string_quote_removal (temp->redirectee.filename->word, 0);
584
585 /* redirection_expand will return NULL if the expansion results in
586 multiple words or no words. Check for that here, and just abort
587 this here document if it does. */
588 if (redir_word)
589 redir_len = strlen (redir_word);
590 else
591 {
592 temp->here_doc_eof = (char *)xmalloc (1);
593 temp->here_doc_eof[0] = '\0';
594 goto document_done;
595 }
596
597 free (temp->redirectee.filename->word);
598 temp->here_doc_eof = redir_word;
599
600 /* Read lines from wherever lines are coming from.
601 For each line read, if kill_leading, then kill the
602 leading tab characters.
603 If the line matches redir_word exactly, then we have
604 manufactured the document. Otherwise, add the line to the
605 list of lines in the document. */
606
607 /* If the here-document delimiter was quoted, the lines should
608 be read verbatim from the input. If it was not quoted, we
609 need to perform backslash-quoted newline removal. */
610 delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
611 while (full_line = read_secondary_line (delim_unquoted))
612 {
613 register char *line;
614 int len;
615
616 here_doc_first_line = 0;
617 line = full_line;
618 line_number++;
619
620 /* If set -v is in effect, echo the line read. read_secondary_line/
621 read_a_line leaves the newline at the end, so don't print another. */
622 if (echo_input_at_read)
623 fprintf (stderr, "%s", line);
624
625 if (kill_leading && *line)
626 {
627 /* Hack: To be compatible with some Bourne shells, we
628 check the word before stripping the whitespace. This
629 is a hack, though. */
630 if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
631 goto document_done;
632
633 while (*line == '\t')
634 line++;
635 }
636
637 if (*line == 0)
638 continue;
639
640 if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
641 goto document_done;
642
643 len = strlen (line);
644 if (len + document_index >= document_size)
645 {
646 document_size = document_size ? 2 * (document_size + len) : len + 2;
647 document = (char *)xrealloc (document, document_size);
648 }
649
650 /* len is guaranteed to be > 0 because of the check for line
651 being an empty string before the call to strlen. */
652 FASTCOPY (line, document + document_index, len);
653 document_index += len;
654 }
655
656 if (full_line == 0)
657 internal_warning (_("here-document at line %d delimited by end-of-file (wanted `%s')"), lineno, redir_word);
658
659 document_done:
660 if (document)
661 document[document_index] = '\0';
662 else
663 {
664 document = (char *)xmalloc (1);
665 document[0] = '\0';
666 }
667 temp->redirectee.filename->word = document;
668 here_doc_first_line = 0;
669 }
670
671 /* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION.
672 INSTRUCTION is the instruction type, SOURCE is a file descriptor,
673 and DEST is a file descriptor or a WORD_DESC *. */
674 REDIRECT *
675 make_redirection (source, instruction, dest_and_filename, flags)
676 REDIRECTEE source;
677 enum r_instruction instruction;
678 REDIRECTEE dest_and_filename;
679 int flags;
680 {
681 REDIRECT *temp;
682 WORD_DESC *w;
683 int wlen;
684 intmax_t lfd;
685
686 temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));
687
688 /* First do the common cases. */
689 temp->redirector = source;
690 temp->redirectee = dest_and_filename;
691 temp->here_doc_eof = 0;
692 temp->instruction = instruction;
693 temp->flags = 0;
694 temp->rflags = flags;
695 temp->next = (REDIRECT *)NULL;
696
697 switch (instruction)
698 {
699
700 case r_output_direction: /* >foo */
701 case r_output_force: /* >| foo */
702 case r_err_and_out: /* &>filename */
703 temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
704 break;
705
706 case r_appending_to: /* >>foo */
707 case r_append_err_and_out: /* &>> filename */
708 temp->flags = O_APPEND | O_WRONLY | O_CREAT;
709 break;
710
711 case r_input_direction: /* <foo */
712 case r_inputa_direction: /* foo & makes this. */
713 temp->flags = O_RDONLY;
714 break;
715
716 case r_input_output: /* <>foo */
717 temp->flags = O_RDWR | O_CREAT;
718 break;
719
720 case r_deblank_reading_until: /* <<-foo */
721 case r_reading_until: /* << foo */
722 case r_reading_string: /* <<< foo */
723 case r_close_this: /* <&- */
724 case r_duplicating_input: /* 1<&2 */
725 case r_duplicating_output: /* 1>&2 */
726 break;
727
728 /* the parser doesn't pass these. */
729 case r_move_input: /* 1<&2- */
730 case r_move_output: /* 1>&2- */
731 case r_move_input_word: /* 1<&$foo- */
732 case r_move_output_word: /* 1>&$foo- */
733 break;
734
735 /* The way the lexer works we have to do this here. */
736 case r_duplicating_input_word: /* 1<&$foo */
737 case r_duplicating_output_word: /* 1>&$foo */
738 w = dest_and_filename.filename;
739 wlen = strlen (w->word) - 1;
740 if (w->word[wlen] == '-') /* Yuck */
741 {
742 w->word[wlen] = '\0';
743 if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd)
744 {
745 dispose_word (w);
746 temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output;
747 temp->redirectee.dest = lfd;
748 }
749 else
750 temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word;
751 }
752
753 break;
754
755 default:
756 programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction);
757 abort ();
758 break;
759 }
760 return (temp);
761 }
762
763 COMMAND *
764 make_function_def (name, command, lineno, lstart)
765 WORD_DESC *name;
766 COMMAND *command;
767 int lineno, lstart;
768 {
769 FUNCTION_DEF *temp;
770 #if defined (ARRAY_VARS)
771 SHELL_VAR *bash_source_v;
772 ARRAY *bash_source_a;
773 #endif
774
775 temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
776 temp->command = command;
777 temp->name = name;
778 temp->line = lineno;
779 temp->flags = 0;
780 command->line = lstart;
781
782 /* Information used primarily for debugging. */
783 temp->source_file = 0;
784 #if defined (ARRAY_VARS)
785 GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
786 if (bash_source_a && array_num_elements (bash_source_a) > 0)
787 temp->source_file = array_reference (bash_source_a, 0);
788 #endif
789 /* Assume that shell functions without a source file before the shell is
790 initialized come from the environment. Otherwise default to "main"
791 (usually functions being defined interactively) */
792 if (temp->source_file == 0)
793 temp->source_file = shell_initialized ? "main" : "environment";
794
795 #if defined (DEBUGGER)
796 bind_function_def (name->word, temp, 0);
797 #endif
798
799 temp->source_file = temp->source_file ? savestring (temp->source_file) : 0;
800
801 return (make_command (cm_function_def, (SIMPLE_COM *)temp));
802 }
803
804 COMMAND *
805 make_subshell_command (command)
806 COMMAND *command;
807 {
808 SUBSHELL_COM *temp;
809
810 temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
811 temp->command = command;
812 temp->flags = CMD_WANT_SUBSHELL;
813 temp->line = line_number;
814 return (make_command (cm_subshell, (SIMPLE_COM *)temp));
815 }
816
817 COMMAND *
818 make_coproc_command (name, command)
819 char *name;
820 COMMAND *command;
821 {
822 COPROC_COM *temp;
823
824 temp = (COPROC_COM *)xmalloc (sizeof (COPROC_COM));
825 temp->name = savestring (name);
826 temp->command = command;
827 temp->flags = CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
828 return (make_command (cm_coproc, (SIMPLE_COM *)temp));
829 }
830
831 /* Reverse the word list and redirection list in the simple command
832 has just been parsed. It seems simpler to do this here the one
833 time then by any other method that I can think of. */
834 COMMAND *
835 clean_simple_command (command)
836 COMMAND *command;
837 {
838 if (command->type != cm_simple)
839 command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0);
840 else
841 {
842 command->value.Simple->words =
843 REVERSE_LIST (command->value.Simple->words, WORD_LIST *);
844 command->value.Simple->redirects =
845 REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
846 }
847
848 parser_state &= ~PST_REDIRLIST;
849 return (command);
850 }
851
852 /* The Yacc grammar productions have a problem, in that they take a
853 list followed by an ampersand (`&') and do a simple command connection,
854 making the entire list effectively asynchronous, instead of just
855 the last command. This means that when the list is executed, all
856 the commands have stdin set to /dev/null when job control is not
857 active, instead of just the last. This is wrong, and needs fixing
858 up. This function takes the `&' and applies it to the last command
859 in the list. This is done only for lists connected by `;'; it makes
860 `;' bind `tighter' than `&'. */
861 COMMAND *
862 connect_async_list (command, command2, connector)
863 COMMAND *command, *command2;
864 int connector;
865 {
866 COMMAND *t, *t1, *t2;
867
868 t1 = command;
869 t = command->value.Connection->second;
870
871 if (!t || (command->flags & CMD_WANT_SUBSHELL) ||
872 command->value.Connection->connector != ';')
873 {
874 t = command_connect (command, command2, connector);
875 return t;
876 }
877
878 /* This is just defensive programming. The Yacc precedence rules
879 will generally hand this function a command where t points directly
880 to the command we want (e.g. given a ; b ; c ; d &, t1 will point
881 to the `a ; b ; c' list and t will be the `d'). We only want to do
882 this if the list is not being executed as a unit in the background
883 with `( ... )', so we have to check for CMD_WANT_SUBSHELL. That's
884 the only way to tell. */
885 while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection &&
886 t->value.Connection->connector == ';')
887 {
888 t1 = t;
889 t = t->value.Connection->second;
890 }
891 /* Now we have t pointing to the last command in the list, and
892 t1->value.Connection->second == t. */
893 t2 = command_connect (t, command2, connector);
894 t1->value.Connection->second = t2;
895 return command;
896 }