]> git.ipfire.org Git - thirdparty/bash.git/blame - make_cmd.c
Bash-4.2 patch 29
[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;
f73dda09 283 int nsemi;
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 */
295 while (*s && *s != ';')
28ef6c31 296 s++;
bb70624e
JA
297
298 t = (s > start) ? substring (start, 0, s - start) : (char *)NULL;
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);
bb70624e
JA
327 last_command_exit_value = 2;
328 return ((COMMAND *)NULL);
329 }
330
331 temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
332 temp->flags = 0;
333 temp->line = lineno;
334 temp->init = init ? init : make_arith_for_expr ("1");
335 temp->test = test ? test : make_arith_for_expr ("1");
336 temp->step = step ? step : make_arith_for_expr ("1");
337 temp->action = action;
338
b80f6443 339 dispose_words (exprs);
bb70624e
JA
340 return (make_command (cm_arith_for, (SIMPLE_COM *)temp));
341#else
b80f6443 342 dispose_words (exprs);
bb70624e
JA
343 last_command_exit_value = 2;
344 return ((COMMAND *)NULL);
345#endif /* ARITH_FOR_COMMAND */
346}
347
726f6388
JA
348COMMAND *
349make_group_command (command)
350 COMMAND *command;
351{
ccc6cda3 352 GROUP_COM *temp;
726f6388 353
ccc6cda3 354 temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
726f6388
JA
355 temp->command = command;
356 return (make_command (cm_group, (SIMPLE_COM *)temp));
357}
358
359COMMAND *
b80f6443 360make_case_command (word, clauses, lineno)
726f6388
JA
361 WORD_DESC *word;
362 PATTERN_LIST *clauses;
95732b49 363 int lineno;
726f6388
JA
364{
365 CASE_COM *temp;
366
367 temp = (CASE_COM *)xmalloc (sizeof (CASE_COM));
368 temp->flags = 0;
b80f6443 369 temp->line = lineno;
726f6388
JA
370 temp->word = word;
371 temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *);
372 return (make_command (cm_case, (SIMPLE_COM *)temp));
373}
374
375PATTERN_LIST *
376make_pattern_list (patterns, action)
377 WORD_LIST *patterns;
378 COMMAND *action;
379{
380 PATTERN_LIST *temp;
381
382 temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
383 temp->patterns = REVERSE_LIST (patterns, WORD_LIST *);
384 temp->action = action;
385 temp->next = NULL;
95732b49 386 temp->flags = 0;
726f6388
JA
387 return (temp);
388}
389
390COMMAND *
391make_if_command (test, true_case, false_case)
392 COMMAND *test, *true_case, *false_case;
393{
394 IF_COM *temp;
395
396 temp = (IF_COM *)xmalloc (sizeof (IF_COM));
397 temp->flags = 0;
398 temp->test = test;
399 temp->true_case = true_case;
400 temp->false_case = false_case;
401 return (make_command (cm_if, (SIMPLE_COM *)temp));
402}
403
404static COMMAND *
ccc6cda3 405make_until_or_while (which, test, action)
726f6388 406 enum command_type which;
ccc6cda3 407 COMMAND *test, *action;
726f6388
JA
408{
409 WHILE_COM *temp;
410
411 temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
412 temp->flags = 0;
413 temp->test = test;
414 temp->action = action;
415 return (make_command (which, (SIMPLE_COM *)temp));
416}
417
418COMMAND *
419make_while_command (test, action)
420 COMMAND *test, *action;
421{
ccc6cda3 422 return (make_until_or_while (cm_while, test, action));
726f6388
JA
423}
424
425COMMAND *
426make_until_command (test, action)
427 COMMAND *test, *action;
428{
ccc6cda3 429 return (make_until_or_while (cm_until, test, action));
726f6388
JA
430}
431
cce855bc
JA
432COMMAND *
433make_arith_command (exp)
434 WORD_LIST *exp;
435{
436#if defined (DPAREN_ARITHMETIC)
437 COMMAND *command;
438 ARITH_COM *temp;
439
440 command = (COMMAND *)xmalloc (sizeof (COMMAND));
441 command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
442
443 temp->flags = 0;
444 temp->line = line_number;
445 temp->exp = exp;
446
447 command->type = cm_arith;
448 command->redirects = (REDIRECT *)NULL;
449 command->flags = 0;
450
451 return (command);
452#else
bb70624e 453 last_command_exit_value = 2;
cce855bc
JA
454 return ((COMMAND *)NULL);
455#endif
456}
457
458#if defined (COND_COMMAND)
459struct cond_com *
460make_cond_node (type, op, left, right)
461 int type;
462 WORD_DESC *op;
463 struct cond_com *left, *right;
464{
465 COND_COM *temp;
466
467 temp = (COND_COM *)xmalloc (sizeof (COND_COM));
468 temp->flags = 0;
469 temp->line = line_number;
470 temp->type = type;
471 temp->op = op;
472 temp->left = left;
473 temp->right = right;
474
475 return (temp);
476}
477#endif
478
479COMMAND *
480make_cond_command (cond_node)
481 COND_COM *cond_node;
482{
483#if defined (COND_COMMAND)
484 COMMAND *command;
485
486 command = (COMMAND *)xmalloc (sizeof (COMMAND));
487 command->value.Cond = cond_node;
488
489 command->type = cm_cond;
490 command->redirects = (REDIRECT *)NULL;
491 command->flags = 0;
b72432fd 492 command->line = cond_node ? cond_node->line : 0;
cce855bc
JA
493
494 return (command);
495#else
bb70624e 496 last_command_exit_value = 2;
cce855bc
JA
497 return ((COMMAND *)NULL);
498#endif
499}
500
726f6388
JA
501COMMAND *
502make_bare_simple_command ()
503{
504 COMMAND *command;
ccc6cda3
JA
505 SIMPLE_COM *temp;
506
507 command = (COMMAND *)xmalloc (sizeof (COMMAND));
508 command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
726f6388
JA
509
510 temp->flags = 0;
511 temp->line = line_number;
512 temp->words = (WORD_LIST *)NULL;
513 temp->redirects = (REDIRECT *)NULL;
ccc6cda3 514
726f6388
JA
515 command->type = cm_simple;
516 command->redirects = (REDIRECT *)NULL;
517 command->flags = 0;
ccc6cda3 518
726f6388
JA
519 return (command);
520}
521
522/* Return a command which is the connection of the word or redirection
523 in ELEMENT, and the command * or NULL in COMMAND. */
524COMMAND *
525make_simple_command (element, command)
526 ELEMENT element;
527 COMMAND *command;
528{
529 /* If we are starting from scratch, then make the initial command
530 structure. Also note that we have to fill in all the slots, since
531 malloc doesn't return zeroed space. */
0001803f
CR
532 if (command == 0)
533 {
534 command = make_bare_simple_command ();
535 parser_state |= PST_REDIRLIST;
536 }
ccc6cda3 537
726f6388 538 if (element.word)
0001803f
CR
539 {
540 command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
541 parser_state &= ~PST_REDIRLIST;
542 }
b80f6443 543 else if (element.redirect)
726f6388
JA
544 {
545 REDIRECT *r = element.redirect;
546 /* Due to the way <> is implemented, there may be more than a single
547 redirection in element.redirect. We just follow the chain as far
548 as it goes, and hook onto the end. */
549 while (r->next)
550 r = r->next;
551 r->next = command->value.Simple->redirects;
552 command->value.Simple->redirects = element.redirect;
553 }
0001803f 554
726f6388
JA
555 return (command);
556}
557
ccc6cda3
JA
558/* Because we are Bourne compatible, we read the input for this
559 << or <<- redirection now, from wherever input is coming from.
560 We store the input read into a WORD_DESC. Replace the text of
561 the redirectee.word with the new input text. If <<- is on,
562 then remove leading TABS from each line. */
726f6388 563void
3185942a 564make_here_document (temp, lineno)
726f6388 565 REDIRECT *temp;
3185942a 566 int lineno;
726f6388 567{
ccc6cda3
JA
568 int kill_leading, redir_len;
569 char *redir_word, *document, *full_line;
570 int document_index, document_size, delim_unquoted;
571
572 if (temp->instruction != r_deblank_reading_until &&
573 temp->instruction != r_reading_until)
574 {
b80f6443 575 internal_error (_("make_here_document: bad instruction type %d"), temp->instruction);
ccc6cda3
JA
576 return;
577 }
578
579 kill_leading = temp->instruction == r_deblank_reading_until;
580
581 document = (char *)NULL;
582 document_index = document_size = 0;
583
584 /* Quote removal is the only expansion performed on the delimiter
585 for here documents, making it an extremely special case. */
586 redir_word = string_quote_removal (temp->redirectee.filename->word, 0);
587
588 /* redirection_expand will return NULL if the expansion results in
589 multiple words or no words. Check for that here, and just abort
590 this here document if it does. */
591 if (redir_word)
592 redir_len = strlen (redir_word);
593 else
594 {
f73dda09 595 temp->here_doc_eof = (char *)xmalloc (1);
ccc6cda3
JA
596 temp->here_doc_eof[0] = '\0';
597 goto document_done;
598 }
726f6388 599
ccc6cda3
JA
600 free (temp->redirectee.filename->word);
601 temp->here_doc_eof = redir_word;
602
603 /* Read lines from wherever lines are coming from.
604 For each line read, if kill_leading, then kill the
605 leading tab characters.
606 If the line matches redir_word exactly, then we have
607 manufactured the document. Otherwise, add the line to the
608 list of lines in the document. */
609
610 /* If the here-document delimiter was quoted, the lines should
611 be read verbatim from the input. If it was not quoted, we
612 need to perform backslash-quoted newline removal. */
613 delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
614 while (full_line = read_secondary_line (delim_unquoted))
726f6388 615 {
ccc6cda3
JA
616 register char *line;
617 int len;
618
619 line = full_line;
620 line_number++;
621
0628567a
JA
622 /* If set -v is in effect, echo the line read. read_secondary_line/
623 read_a_line leaves the newline at the end, so don't print another. */
624 if (echo_input_at_read)
625 fprintf (stderr, "%s", line);
626
ccc6cda3 627 if (kill_leading && *line)
28ef6c31 628 {
ccc6cda3
JA
629 /* Hack: To be compatible with some Bourne shells, we
630 check the word before stripping the whitespace. This
631 is a hack, though. */
632 if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
633 goto document_done;
634
635 while (*line == '\t')
636 line++;
637 }
638
639 if (*line == 0)
28ef6c31 640 continue;
ccc6cda3
JA
641
642 if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
643 goto document_done;
644
645 len = strlen (line);
646 if (len + document_index >= document_size)
726f6388 647 {
bc4cd23c 648 document_size = document_size ? 2 * (document_size + len) : len + 2;
f73dda09 649 document = (char *)xrealloc (document, document_size);
726f6388 650 }
ccc6cda3
JA
651
652 /* len is guaranteed to be > 0 because of the check for line
653 being an empty string before the call to strlen. */
654 FASTCOPY (line, document + document_index, len);
655 document_index += len;
656 }
657
3185942a
JA
658 if (full_line == 0)
659 internal_warning (_("here-document at line %d delimited by end-of-file (wanted `%s')"), lineno, redir_word);
660
ccc6cda3
JA
661document_done:
662 if (document)
663 document[document_index] = '\0';
664 else
665 {
f73dda09 666 document = (char *)xmalloc (1);
ccc6cda3 667 document[0] = '\0';
726f6388 668 }
ccc6cda3 669 temp->redirectee.filename->word = document;
726f6388 670}
ccc6cda3
JA
671
672/* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION.
726f6388
JA
673 INSTRUCTION is the instruction type, SOURCE is a file descriptor,
674 and DEST is a file descriptor or a WORD_DESC *. */
675REDIRECT *
0001803f
CR
676make_redirection (source, instruction, dest_and_filename, flags)
677 REDIRECTEE source;
726f6388
JA
678 enum r_instruction instruction;
679 REDIRECTEE dest_and_filename;
0001803f 680 int flags;
726f6388 681{
7117c2d2
JA
682 REDIRECT *temp;
683 WORD_DESC *w;
684 int wlen;
685 intmax_t lfd;
686
687 temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));
726f6388
JA
688
689 /* First do the common cases. */
690 temp->redirector = source;
691 temp->redirectee = dest_and_filename;
692 temp->instruction = instruction;
693 temp->flags = 0;
0001803f 694 temp->rflags = flags;
726f6388
JA
695 temp->next = (REDIRECT *)NULL;
696
697 switch (instruction)
698 {
699
d166f048
JA
700 case r_output_direction: /* >foo */
701 case r_output_force: /* >| foo */
3185942a 702 case r_err_and_out: /* &>filename */
726f6388
JA
703 temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
704 break;
705
d166f048 706 case r_appending_to: /* >>foo */
3185942a 707 case r_append_err_and_out: /* &>> filename */
d166f048 708 temp->flags = O_APPEND | O_WRONLY | O_CREAT;
726f6388
JA
709 break;
710
d166f048
JA
711 case r_input_direction: /* <foo */
712 case r_inputa_direction: /* foo & makes this. */
713 temp->flags = O_RDONLY;
726f6388
JA
714 break;
715
d166f048
JA
716 case r_input_output: /* <>foo */
717 temp->flags = O_RDWR | O_CREAT;
726f6388
JA
718 break;
719
d166f048
JA
720 case r_deblank_reading_until: /* <<-foo */
721 case r_reading_until: /* << foo */
7117c2d2 722 case r_reading_string: /* <<< foo */
ccc6cda3 723 case r_close_this: /* <&- */
726f6388
JA
724 case r_duplicating_input: /* 1<&2 */
725 case r_duplicating_output: /* 1>&2 */
7117c2d2
JA
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. */
726f6388
JA
736 case r_duplicating_input_word: /* 1<&$foo */
737 case r_duplicating_output_word: /* 1>&$foo */
7117c2d2
JA
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
726f6388 753 break;
ccc6cda3 754
726f6388 755 default:
b80f6443 756 programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction);
726f6388
JA
757 abort ();
758 break;
759 }
760 return (temp);
761}
762
763COMMAND *
ccc6cda3 764make_function_def (name, command, lineno, lstart)
726f6388
JA
765 WORD_DESC *name;
766 COMMAND *command;
ccc6cda3 767 int lineno, lstart;
726f6388
JA
768{
769 FUNCTION_DEF *temp;
b80f6443
JA
770#if defined (ARRAY_VARS)
771 SHELL_VAR *bash_source_v;
772 ARRAY *bash_source_a;
b80f6443 773#endif
726f6388
JA
774
775 temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
776 temp->command = command;
777 temp->name = name;
ccc6cda3 778 temp->line = lineno;
cce855bc 779 temp->flags = 0;
ccc6cda3 780 command->line = lstart;
b80f6443
JA
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
3185942a 789#if defined (DEBUGGER)
b80f6443 790 bind_function_def (name->word, temp);
3185942a 791#endif
b80f6443
JA
792
793 temp->source_file = 0;
726f6388
JA
794 return (make_command (cm_function_def, (SIMPLE_COM *)temp));
795}
796
bb70624e
JA
797COMMAND *
798make_subshell_command (command)
799 COMMAND *command;
800{
801 SUBSHELL_COM *temp;
802
803 temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
804 temp->command = command;
805 temp->flags = CMD_WANT_SUBSHELL;
806 return (make_command (cm_subshell, (SIMPLE_COM *)temp));
807}
808
3185942a
JA
809COMMAND *
810make_coproc_command (name, command)
811 char *name;
812 COMMAND *command;
813{
814 COPROC_COM *temp;
815
816 temp = (COPROC_COM *)xmalloc (sizeof (COPROC_COM));
817 temp->name = savestring (name);
818 temp->command = command;
819 temp->flags = CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
820 return (make_command (cm_coproc, (SIMPLE_COM *)temp));
821}
822
726f6388
JA
823/* Reverse the word list and redirection list in the simple command
824 has just been parsed. It seems simpler to do this here the one
825 time then by any other method that I can think of. */
826COMMAND *
827clean_simple_command (command)
828 COMMAND *command;
829{
830 if (command->type != cm_simple)
b72432fd 831 command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0);
726f6388
JA
832 else
833 {
834 command->value.Simple->words =
835 REVERSE_LIST (command->value.Simple->words, WORD_LIST *);
ccc6cda3 836 command->value.Simple->redirects =
726f6388
JA
837 REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
838 }
839
0001803f 840 parser_state &= ~PST_REDIRLIST;
726f6388
JA
841 return (command);
842}
843
726f6388
JA
844/* The Yacc grammar productions have a problem, in that they take a
845 list followed by an ampersand (`&') and do a simple command connection,
846 making the entire list effectively asynchronous, instead of just
847 the last command. This means that when the list is executed, all
848 the commands have stdin set to /dev/null when job control is not
849 active, instead of just the last. This is wrong, and needs fixing
850 up. This function takes the `&' and applies it to the last command
851 in the list. This is done only for lists connected by `;'; it makes
852 `;' bind `tighter' than `&'. */
853COMMAND *
854connect_async_list (command, command2, connector)
855 COMMAND *command, *command2;
856 int connector;
857{
858 COMMAND *t, *t1, *t2;
859
860 t1 = command;
861 t = command->value.Connection->second;
862
863 if (!t || (command->flags & CMD_WANT_SUBSHELL) ||
864 command->value.Connection->connector != ';')
865 {
866 t = command_connect (command, command2, connector);
867 return t;
868 }
869
870 /* This is just defensive programming. The Yacc precedence rules
871 will generally hand this function a command where t points directly
872 to the command we want (e.g. given a ; b ; c ; d &, t1 will point
873 to the `a ; b ; c' list and t will be the `d'). We only want to do
874 this if the list is not being executed as a unit in the background
875 with `( ... )', so we have to check for CMD_WANT_SUBSHELL. That's
876 the only way to tell. */
877 while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection &&
878 t->value.Connection->connector == ';')
879 {
880 t1 = t;
881 t = t->value.Connection->second;
882 }
883 /* Now we have t pointing to the last command in the list, and
884 t1->value.Connection->second == t. */
885 t2 = command_connect (t, command2, connector);
886 t1->value.Connection->second = t2;
887 return command;
888}