commit bash-20051123 snapshot
[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-2005 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 alloc_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
90 WORD_DESC *
91 make_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
109 WORD_DESC *
110 make_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
142 WORD_DESC *
143 make_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
152 WORD_DESC *
153 make_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
164 WORD_LIST *
165 make_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
178 COMMAND *
179 make_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
193 COMMAND *
194 command_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
207 static COMMAND *
208 make_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
226 COMMAND *
227 make_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
236 COMMAND *
237 make_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)
252 static WORD_LIST *
253 make_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;     /* 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. */
272 COMMAND *
273 make_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
347 COMMAND *
348 make_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
358 COMMAND *
359 make_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
374 PATTERN_LIST *
375 make_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   return (temp);
386 }
387
388 COMMAND *
389 make_if_command (test, true_case, false_case)
390      COMMAND *test, *true_case, *false_case;
391 {
392   IF_COM *temp;
393
394   temp = (IF_COM *)xmalloc (sizeof (IF_COM));
395   temp->flags = 0;
396   temp->test = test;
397   temp->true_case = true_case;
398   temp->false_case = false_case;
399   return (make_command (cm_if, (SIMPLE_COM *)temp));
400 }
401
402 static COMMAND *
403 make_until_or_while (which, test, action)
404      enum command_type which;
405      COMMAND *test, *action;
406 {
407   WHILE_COM *temp;
408
409   temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
410   temp->flags = 0;
411   temp->test = test;
412   temp->action = action;
413   return (make_command (which, (SIMPLE_COM *)temp));
414 }
415
416 COMMAND *
417 make_while_command (test, action)
418      COMMAND *test, *action;
419 {
420   return (make_until_or_while (cm_while, test, action));
421 }
422
423 COMMAND *
424 make_until_command (test, action)
425      COMMAND *test, *action;
426 {
427   return (make_until_or_while (cm_until, test, action));
428 }
429
430 COMMAND *
431 make_arith_command (exp)
432      WORD_LIST *exp;
433 {
434 #if defined (DPAREN_ARITHMETIC)
435   COMMAND *command;
436   ARITH_COM *temp;
437
438   command = (COMMAND *)xmalloc (sizeof (COMMAND));
439   command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
440
441   temp->flags = 0;
442   temp->line = line_number;
443   temp->exp = exp;
444
445   command->type = cm_arith;
446   command->redirects = (REDIRECT *)NULL;
447   command->flags = 0;
448
449   return (command);
450 #else
451   last_command_exit_value = 2;
452   return ((COMMAND *)NULL);
453 #endif
454 }
455
456 #if defined (COND_COMMAND)
457 struct cond_com *
458 make_cond_node (type, op, left, right)
459      int type;
460      WORD_DESC *op;
461      struct cond_com *left, *right;
462 {
463   COND_COM *temp;
464
465   temp = (COND_COM *)xmalloc (sizeof (COND_COM));
466   temp->flags = 0;
467   temp->line = line_number;
468   temp->type = type;
469   temp->op = op;
470   temp->left = left;
471   temp->right = right;
472
473   return (temp);
474 }
475 #endif
476
477 COMMAND *
478 make_cond_command (cond_node)
479      COND_COM *cond_node;
480 {
481 #if defined (COND_COMMAND)
482   COMMAND *command;
483
484   command = (COMMAND *)xmalloc (sizeof (COMMAND));
485   command->value.Cond = cond_node;
486
487   command->type = cm_cond;
488   command->redirects = (REDIRECT *)NULL;
489   command->flags = 0;
490   command->line = cond_node ? cond_node->line : 0;
491
492   return (command);
493 #else
494   last_command_exit_value = 2;
495   return ((COMMAND *)NULL);
496 #endif
497 }
498
499 COMMAND *
500 make_bare_simple_command ()
501 {
502   COMMAND *command;
503   SIMPLE_COM *temp;
504
505   command = (COMMAND *)xmalloc (sizeof (COMMAND));
506   command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
507
508   temp->flags = 0;
509   temp->line = line_number;
510   temp->words = (WORD_LIST *)NULL;
511   temp->redirects = (REDIRECT *)NULL;
512
513   command->type = cm_simple;
514   command->redirects = (REDIRECT *)NULL;
515   command->flags = 0;
516
517   return (command);
518 }
519
520 /* Return a command which is the connection of the word or redirection
521    in ELEMENT, and the command * or NULL in COMMAND. */
522 COMMAND *
523 make_simple_command (element, command)
524      ELEMENT element;
525      COMMAND *command;
526 {
527   /* If we are starting from scratch, then make the initial command
528      structure.  Also note that we have to fill in all the slots, since
529      malloc doesn't return zeroed space. */
530   if (!command)
531     command = make_bare_simple_command ();
532
533   if (element.word)
534     command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
535   else if (element.redirect)
536     {
537       REDIRECT *r = element.redirect;
538       /* Due to the way <> is implemented, there may be more than a single
539          redirection in element.redirect.  We just follow the chain as far
540          as it goes, and hook onto the end. */
541       while (r->next)
542         r = r->next;
543       r->next = command->value.Simple->redirects;
544       command->value.Simple->redirects = element.redirect;
545     }
546   return (command);
547 }
548
549 /* Because we are Bourne compatible, we read the input for this
550    << or <<- redirection now, from wherever input is coming from.
551    We store the input read into a WORD_DESC.  Replace the text of
552    the redirectee.word with the new input text.  If <<- is on,
553    then remove leading TABS from each line. */
554 void
555 make_here_document (temp)
556      REDIRECT *temp;
557 {
558   int kill_leading, redir_len;
559   char *redir_word, *document, *full_line;
560   int document_index, document_size, delim_unquoted;
561
562   if (temp->instruction != r_deblank_reading_until &&
563       temp->instruction != r_reading_until)
564     {
565       internal_error (_("make_here_document: bad instruction type %d"), temp->instruction);
566       return;
567     }
568
569   kill_leading = temp->instruction == r_deblank_reading_until;
570
571   document = (char *)NULL;
572   document_index = document_size = 0;
573
574   /* Quote removal is the only expansion performed on the delimiter
575      for here documents, making it an extremely special case. */
576   redir_word = string_quote_removal (temp->redirectee.filename->word, 0);
577
578   /* redirection_expand will return NULL if the expansion results in
579      multiple words or no words.  Check for that here, and just abort
580      this here document if it does. */
581   if (redir_word)
582     redir_len = strlen (redir_word);
583   else
584     {
585       temp->here_doc_eof = (char *)xmalloc (1);
586       temp->here_doc_eof[0] = '\0';
587       goto document_done;
588     }
589
590   free (temp->redirectee.filename->word);
591   temp->here_doc_eof = redir_word;
592
593   /* Read lines from wherever lines are coming from.
594      For each line read, if kill_leading, then kill the
595      leading tab characters.
596      If the line matches redir_word exactly, then we have
597      manufactured the document.  Otherwise, add the line to the
598      list of lines in the document. */
599
600   /* If the here-document delimiter was quoted, the lines should
601      be read verbatim from the input.  If it was not quoted, we
602      need to perform backslash-quoted newline removal. */
603   delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
604   while (full_line = read_secondary_line (delim_unquoted))
605     {
606       register char *line;
607       int len;
608
609       line = full_line;
610       line_number++;
611
612       if (kill_leading && *line)
613         {
614           /* Hack:  To be compatible with some Bourne shells, we
615              check the word before stripping the whitespace.  This
616              is a hack, though. */
617           if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
618             goto document_done;
619
620           while (*line == '\t')
621             line++;
622         }
623
624       if (*line == 0)
625         continue;
626
627       if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
628         goto document_done;
629
630       len = strlen (line);
631       if (len + document_index >= document_size)
632         {
633           document_size = document_size ? 2 * (document_size + len) : len + 2;
634           document = (char *)xrealloc (document, document_size);
635         }
636
637       /* len is guaranteed to be > 0 because of the check for line
638          being an empty string before the call to strlen. */
639       FASTCOPY (line, document + document_index, len);
640       document_index += len;
641     }
642
643 document_done:
644   if (document)
645     document[document_index] = '\0';
646   else
647     {
648       document = (char *)xmalloc (1);
649       document[0] = '\0';
650     }
651   temp->redirectee.filename->word = document;
652 }
653
654 /* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION.
655    INSTRUCTION is the instruction type, SOURCE is a file descriptor,
656    and DEST is a file descriptor or a WORD_DESC *. */
657 REDIRECT *
658 make_redirection (source, instruction, dest_and_filename)
659      int source;
660      enum r_instruction instruction;
661      REDIRECTEE dest_and_filename;
662 {
663   REDIRECT *temp;
664   WORD_DESC *w;
665   int wlen;
666   intmax_t lfd;
667
668   temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));
669
670   /* First do the common cases. */
671   temp->redirector = source;
672   temp->redirectee = dest_and_filename;
673   temp->instruction = instruction;
674   temp->flags = 0;
675   temp->next = (REDIRECT *)NULL;
676
677   switch (instruction)
678     {
679
680     case r_output_direction:            /* >foo */
681     case r_output_force:                /* >| foo */
682     case r_err_and_out:                 /* command &>filename */
683       temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
684       break;
685
686     case r_appending_to:                /* >>foo */
687       temp->flags = O_APPEND | O_WRONLY | O_CREAT;
688       break;
689
690     case r_input_direction:             /* <foo */
691     case r_inputa_direction:            /* foo & makes this. */
692       temp->flags = O_RDONLY;
693       break;
694
695     case r_input_output:                /* <>foo */
696       temp->flags = O_RDWR | O_CREAT;
697       break;
698
699     case r_deblank_reading_until:       /* <<-foo */
700     case r_reading_until:               /* << foo */
701     case r_reading_string:              /* <<< foo */
702     case r_close_this:                  /* <&- */
703     case r_duplicating_input:           /* 1<&2 */
704     case r_duplicating_output:          /* 1>&2 */
705       break;
706
707     /* the parser doesn't pass these. */
708     case r_move_input:                  /* 1<&2- */
709     case r_move_output:                 /* 1>&2- */
710     case r_move_input_word:             /* 1<&$foo- */
711     case r_move_output_word:            /* 1>&$foo- */
712       break;
713
714     /* The way the lexer works we have to do this here. */
715     case r_duplicating_input_word:      /* 1<&$foo */
716     case r_duplicating_output_word:     /* 1>&$foo */
717       w = dest_and_filename.filename;
718       wlen = strlen (w->word) - 1;
719       if (w->word[wlen] == '-')         /* Yuck */
720         {
721           w->word[wlen] = '\0';
722           if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd)
723             {
724               dispose_word (w);
725               temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output;
726               temp->redirectee.dest = lfd;
727             }
728           else
729             temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word;
730         }
731           
732       break;
733
734     default:
735       programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction);
736       abort ();
737       break;
738     }
739   return (temp);
740 }
741
742 COMMAND *
743 make_function_def (name, command, lineno, lstart)
744      WORD_DESC *name;
745      COMMAND *command;
746      int lineno, lstart;
747 {
748   FUNCTION_DEF *temp;
749 #if defined (ARRAY_VARS)
750   SHELL_VAR *bash_source_v;
751   ARRAY *bash_source_a;
752   char *t;
753 #endif
754
755   temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
756   temp->command = command;
757   temp->name = name;
758   temp->line = lineno;
759   temp->flags = 0;
760   command->line = lstart;
761
762   /* Information used primarily for debugging. */
763   temp->source_file = 0;
764 #if defined (ARRAY_VARS)
765   GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
766   if (bash_source_a && array_num_elements (bash_source_a) > 0)
767     temp->source_file = array_reference (bash_source_a, 0);
768 #endif
769   bind_function_def (name->word, temp);
770
771   temp->source_file = 0;
772   return (make_command (cm_function_def, (SIMPLE_COM *)temp));
773 }
774
775 COMMAND *
776 make_subshell_command (command)
777      COMMAND *command;
778 {
779   SUBSHELL_COM *temp;
780
781   temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
782   temp->command = command;
783   temp->flags = CMD_WANT_SUBSHELL;
784   return (make_command (cm_subshell, (SIMPLE_COM *)temp));
785 }
786
787 /* Reverse the word list and redirection list in the simple command
788    has just been parsed.  It seems simpler to do this here the one
789    time then by any other method that I can think of. */
790 COMMAND *
791 clean_simple_command (command)
792      COMMAND *command;
793 {
794   if (command->type != cm_simple)
795     command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0);
796   else
797     {
798       command->value.Simple->words =
799         REVERSE_LIST (command->value.Simple->words, WORD_LIST *);
800       command->value.Simple->redirects =
801         REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
802     }
803
804   return (command);
805 }
806
807 /* The Yacc grammar productions have a problem, in that they take a
808    list followed by an ampersand (`&') and do a simple command connection,
809    making the entire list effectively asynchronous, instead of just
810    the last command.  This means that when the list is executed, all
811    the commands have stdin set to /dev/null when job control is not
812    active, instead of just the last.  This is wrong, and needs fixing
813    up.  This function takes the `&' and applies it to the last command
814    in the list.  This is done only for lists connected by `;'; it makes
815    `;' bind `tighter' than `&'. */
816 COMMAND *
817 connect_async_list (command, command2, connector)
818      COMMAND *command, *command2;
819      int connector;
820 {
821   COMMAND *t, *t1, *t2;
822
823   t1 = command;
824   t = command->value.Connection->second;
825
826   if (!t || (command->flags & CMD_WANT_SUBSHELL) ||
827       command->value.Connection->connector != ';')
828     {
829       t = command_connect (command, command2, connector);
830       return t;
831     }
832
833   /* This is just defensive programming.  The Yacc precedence rules
834      will generally hand this function a command where t points directly
835      to the command we want (e.g. given a ; b ; c ; d &, t1 will point
836      to the `a ; b ; c' list and t will be the `d').  We only want to do
837      this if the list is not being executed as a unit in the background
838      with `( ... )', so we have to check for CMD_WANT_SUBSHELL.  That's
839      the only way to tell. */
840   while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection &&
841          t->value.Connection->connector == ';')
842     {
843       t1 = t;
844       t = t->value.Connection->second;
845     }
846   /* Now we have t pointing to the last command in the list, and
847      t1->value.Connection->second == t. */
848   t2 = command_connect (t, command2, connector);
849   t1->value.Connection->second = t2;
850   return command;
851 }