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