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