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