Imported from ../bash-2.01.tar.gz.
[platform/upstream/bash.git] / builtins / common.c
1 /* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
2
3    This file is part of GNU Bash, the Bourne Again SHell.
4
5    Bash is free software; you can redistribute it and/or modify it under
6    the terms of the GNU General Public License as published by the Free
7    Software Foundation; either version 1, or (at your option) any later
8    version.
9
10    Bash is distributed in the hope that it will be useful, but WITHOUT ANY
11    WARRANTY; without even the implied warranty of MERCHANTABILITY or
12    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13    for more details.
14    
15    You should have received a copy of the GNU General Public License along
16    with Bash; see the file COPYING.  If not, write to the Free Software
17    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 #include <config.h>
20
21 #if defined (HAVE_UNISTD_H)
22 #  include <unistd.h>
23 #endif
24
25 #include <stdio.h>
26 #include "../bashtypes.h"
27 #include "../posixstat.h"
28 #include <signal.h>
29
30 #if defined (PREFER_STDARG)
31 #  include <stdarg.h>
32 #else
33 #  if defined (PREFER_VARARGS)
34 #    include <varargs.h>
35 #  endif
36 #endif
37
38 #include "../bashansi.h"
39
40 #include "../shell.h"
41 #include "../maxpath.h"
42 #include "../flags.h"
43 #include "../jobs.h"
44 #include "../builtins.h"
45 #include "../input.h"
46 #include "../execute_cmd.h"
47 #include "../trap.h"
48 #include "bashgetopt.h"
49 #include "common.h"
50 #include "builtext.h"
51 #include <tilde/tilde.h>
52
53 #if defined (HISTORY)
54 #  include "../bashhist.h"
55 #endif
56
57 extern int no_symbolic_links, interactive, interactive_shell;
58 extern int indirection_level, startup_state, subshell_environment;
59 extern int line_number;
60 extern int last_command_exit_value;
61 extern int running_trap;
62 extern int variable_context;
63 extern int posixly_correct;
64 extern char *this_command_name, *shell_name;
65 extern COMMAND *global_command;
66 extern char *bash_getcwd_errstr;
67
68 /* Used by some builtins and the mainline code. */
69 Function *last_shell_builtin = (Function *)NULL;
70 Function *this_shell_builtin = (Function *)NULL;
71
72 /* **************************************************************** */
73 /*                                                                  */
74 /*           Error reporting, usage, and option processing          */
75 /*                                                                  */
76 /* **************************************************************** */
77
78 /* This is a lot like report_error (), but it is for shell builtins
79    instead of shell control structures, and it won't ever exit the
80    shell. */
81 #if defined (USE_VARARGS)
82 void
83 #if defined (PREFER_STDARG)
84 builtin_error (const char *format, ...)
85 #else
86 builtin_error (format, va_alist)
87      const char *format;
88      va_dcl
89 #endif
90 {
91   va_list args;
92   char *name;
93
94   name = get_name_for_error ();
95   fprintf (stderr, "%s: ", name);
96
97   if (this_command_name && *this_command_name)
98     fprintf (stderr, "%s: ", this_command_name);
99
100 #if defined (PREFER_STDARG)
101   va_start (args, format);
102 #else
103   va_start (args);
104 #endif
105
106   vfprintf (stderr, format, args);
107   va_end (args);
108   fprintf (stderr, "\n");
109 }
110 #else /* !USE_VARARGS */
111 void
112 builtin_error (format, arg1, arg2, arg3, arg4, arg5)
113      char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
114 {
115   if (this_command_name && *this_command_name)
116     fprintf (stderr, "%s: ", this_command_name);
117
118   fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
119   fprintf (stderr, "\n");
120   fflush (stderr);
121 }
122 #endif /* !USE_VARARGS */
123
124 /* Print a usage summary for the currently-executing builtin command. */
125 void
126 builtin_usage ()
127 {
128   if (this_command_name && *this_command_name)
129     fprintf (stderr, "%s: usage: ", this_command_name);
130   fprintf (stderr, "%s\n", current_builtin->short_doc);
131   fflush (stderr);
132 }
133
134 /* Return if LIST is NULL else barf and jump to top_level.  Used by some
135    builtins that do not accept arguments. */
136 void
137 no_args (list)
138      WORD_LIST *list;
139 {
140   if (list)
141     {
142       builtin_error ("too many arguments");
143       jump_to_top_level (DISCARD);
144     }
145 }
146
147 /* Function called when one of the builtin commands detects a bad
148    option. */
149 void
150 bad_option (s)
151      char *s;
152 {
153   builtin_error ("unknown option: %s", s);
154 }
155
156 /* Check that no options were given to the currently-executing builtin,
157    and return 0 if there were options. */
158 int
159 no_options (list)
160      WORD_LIST *list;
161 {
162   reset_internal_getopt ();
163   if (internal_getopt (list, "") != -1)
164     {
165       builtin_usage ();
166       return (1);
167     }
168   return (0);
169 }
170
171 /* **************************************************************** */
172 /*                                                                  */
173 /*           Shell positional parameter manipulation                */
174 /*                                                                  */
175 /* **************************************************************** */
176
177 /* Convert a WORD_LIST into a C-style argv.  Return the number of elements
178    in the list in *IP, if IP is non-null.  A convenience function for
179    loadable builtins; also used by `test'. */
180 char **
181 make_builtin_argv (list, ip)
182      WORD_LIST *list;
183      int *ip;
184 {
185   char **argv;
186
187   argv = word_list_to_argv (list, 0, 1, ip);
188   argv[0] = this_command_name;
189   return argv;
190 }
191
192 /* Remember LIST in $0 ... $9, and REST_OF_ARGS.  If DESTRUCTIVE is
193    non-zero, then discard whatever the existing arguments are, else
194    only discard the ones that are to be replaced. */
195 void
196 remember_args (list, destructive)
197      WORD_LIST *list;
198      int destructive;
199 {
200   register int i;
201
202   for (i = 1; i < 10; i++)
203     {
204       if ((destructive || list) && dollar_vars[i])
205         {
206           free (dollar_vars[i]);
207           dollar_vars[i] = (char *)NULL;
208         }
209
210       if (list)
211         {
212           dollar_vars[i] = savestring (list->word->word);
213           list = list->next;
214         }
215     }
216
217   /* If arguments remain, assign them to REST_OF_ARGS.
218      Note that copy_word_list (NULL) returns NULL, and
219      that dispose_words (NULL) does nothing. */
220   if (destructive || list)
221     {
222       dispose_words (rest_of_args);
223       rest_of_args = copy_word_list (list);
224     }
225
226   if (destructive)
227     set_dollar_vars_changed ();
228 }
229
230 /* **************************************************************** */
231 /*                                                                  */
232 /*               Pushing and Popping variable contexts              */
233 /*                                                                  */
234 /* **************************************************************** */
235
236 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
237 static int dollar_arg_stack_slots;
238 static int dollar_arg_stack_index;
239
240 void
241 push_context ()
242 {
243   push_dollar_vars ();
244   variable_context++;
245 }
246
247 void
248 pop_context ()
249 {
250   pop_dollar_vars ();
251   kill_all_local_variables ();
252   variable_context--;
253 }
254
255 /* Save the existing positional parameters on a stack. */
256 void
257 push_dollar_vars ()
258 {
259   if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
260     {
261       dollar_arg_stack = (WORD_LIST **)
262         xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
263                   * sizeof (WORD_LIST **));
264     }
265   dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
266   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
267 }
268
269 /* Restore the positional parameters from our stack. */
270 void
271 pop_dollar_vars ()
272 {
273   if (!dollar_arg_stack || dollar_arg_stack_index == 0)
274     return;
275
276   remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
277   dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
278   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
279 }
280
281 void
282 dispose_saved_dollar_vars ()
283 {
284   if (!dollar_arg_stack || dollar_arg_stack_index == 0)
285     return;
286
287   dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
288   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
289 }
290
291 static int changed_dollar_vars;
292
293 /* Have the dollar variables been reset to new values since we last
294    checked? */
295 int
296 dollar_vars_changed ()
297 {
298   return (changed_dollar_vars);
299 }
300
301 void
302 set_dollar_vars_unchanged ()
303 {
304   changed_dollar_vars = 0;
305 }
306
307 void
308 set_dollar_vars_changed ()
309 {
310   changed_dollar_vars = 1;
311 }
312
313 /* **************************************************************** */
314 /*                                                                  */
315 /*              Validating numeric input and arguments              */
316 /*                                                                  */
317 /* **************************************************************** */
318
319 /* Read a numeric arg for this_command_name, the name of the shell builtin
320    that wants it.  LIST is the word list that the arg is to come from.
321    Accept only the numeric argument; report an error if other arguments
322    follow.  If FATAL is true, call throw_to_top_level, which exits the
323    shell; if not, call jump_to_top_level (DISCARD), which aborts the
324    current command. */
325 int
326 get_numeric_arg (list, fatal)
327      WORD_LIST *list;
328      int fatal;
329 {
330   long count = 1;
331
332   if (list)
333     {
334       register char *arg;
335
336       arg = list->word->word;
337       if (!arg || (legal_number (arg, &count) == 0))
338         {
339           builtin_error ("bad non-numeric arg `%s'", list->word->word);
340           if (fatal)
341             throw_to_top_level ();
342           else
343             jump_to_top_level (DISCARD);
344         }
345       no_args (list->next);
346     }
347   return (count);
348 }
349
350 /* Return the octal number parsed from STRING, or -1 to indicate
351    that the string contained a bad number. */
352 int
353 read_octal (string)
354      char *string;
355 {
356   int result, digits;
357
358   result = digits = 0;
359   while (*string && *string >= '0' && *string < '8')
360     {
361       digits++;
362       result = (result * 8) + *string++ - '0';
363     }
364
365   if (!digits || result > 0777 || *string)
366     result = -1;
367
368   return (result);
369 }
370
371 /* **************************************************************** */
372 /*                                                                  */
373 /*           Manipulating the current working directory             */
374 /*                                                                  */
375 /* **************************************************************** */
376
377 /* Return a consed string which is the current working directory.
378    FOR_WHOM is the name of the caller for error printing.  */
379 char *the_current_working_directory = (char *)NULL;
380
381 char *
382 get_working_directory (for_whom)
383      char *for_whom;
384 {
385   char *directory;
386
387   if (no_symbolic_links)
388     {
389       if (the_current_working_directory)
390         free (the_current_working_directory);
391
392       the_current_working_directory = (char *)NULL;
393     }
394
395   if (the_current_working_directory == 0)
396     {
397       the_current_working_directory = xmalloc (PATH_MAX);
398       the_current_working_directory[0] = '\0';
399       directory = getcwd (the_current_working_directory, PATH_MAX);
400       if (directory == 0)
401         {
402           fprintf (stderr, "%s: could not get current directory: %s\n",
403                    (for_whom && *for_whom) ? for_whom : get_name_for_error (),
404                    the_current_working_directory[0]
405                         ? the_current_working_directory
406                         : bash_getcwd_errstr);
407
408           free (the_current_working_directory);
409           the_current_working_directory = (char *)NULL;
410           return (char *)NULL;
411         }
412     }
413
414   return (savestring (the_current_working_directory));
415 }
416
417 /* Make NAME our internal idea of the current working directory. */
418 void
419 set_working_directory (name)
420      char *name;
421 {
422   FREE (the_current_working_directory);
423   the_current_working_directory = savestring (name);
424 }
425
426 /* **************************************************************** */
427 /*                                                                  */
428 /*              Job control support functions                       */
429 /*                                                                  */
430 /* **************************************************************** */
431
432 #if defined (JOB_CONTROL)
433 /* Return the job spec found in LIST. */
434 int
435 get_job_spec (list)
436      WORD_LIST *list;
437 {
438   register char *word;
439   int job, substring;
440
441   if (list == 0)
442     return (current_job);
443
444   word = list->word->word;
445
446   if (*word == '\0')
447     return (current_job);
448
449   if (*word == '%')
450     word++;
451
452   if (digit (*word) && all_digits (word))
453     {
454       job = atoi (word);
455       return (job - 1);
456     }
457
458   substring = 0;
459   switch (*word)
460     {
461     case 0:
462     case '%':
463     case '+':
464       return (current_job);
465
466     case '-':
467       return (previous_job);
468
469     case '?':                   /* Substring search requested. */
470       substring++;
471       word++;
472       /* FALLTHROUGH */
473
474     default:
475       {
476         register int i, wl;
477
478         job = NO_JOB;
479         wl = strlen (word);
480         for (i = 0; i < job_slots; i++)
481           {
482             if (jobs[i])
483               {
484                 register PROCESS *p;
485                 p = jobs[i]->pipe;
486                 do
487                   {
488                     if ((substring && strindex (p->command, word)) ||
489                         (STREQN (p->command, word, wl)))
490                       if (job != NO_JOB)
491                         {
492                           builtin_error ("ambigious job spec: %s", word);
493                           return (DUP_JOB);
494                         }
495                       else
496                         job = i;
497
498                     p = p->next;
499                   }
500                 while (p != jobs[i]->pipe);
501               }
502           }
503         return (job);
504       }
505     }
506 }
507 #endif /* JOB_CONTROL */
508
509 int
510 display_signal_list (list, forcecols)
511      WORD_LIST *list;
512      int forcecols;
513 {
514   register int i, column;
515   char *name;
516   int result;
517   long signum;
518
519   result = EXECUTION_SUCCESS;
520   if (!list)
521     {
522       for (i = 1, column = 0; i < NSIG; i++)
523         {
524           name = signal_name (i);
525           if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
526             continue;
527
528           if (posixly_correct && !forcecols)
529             printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
530           else
531             {
532               printf ("%2d) %s", i, name);
533
534               if (++column < 4)
535                 printf ("\t");
536               else
537                 {
538                   printf ("\n");
539                   column = 0;
540                 }
541             }
542         }
543
544       if ((posixly_correct && !forcecols) || column != 0)
545         printf ("\n");
546       return result;
547     }
548
549   /* List individual signal names or numbers. */
550   while (list)
551     {
552       if (legal_number (list->word->word, &signum))
553         {
554           /* This is specified by Posix.2 so that exit statuses can be
555              mapped into signal numbers. */
556           if (signum > 128)
557             signum -= 128;
558           if (signum < 0 || signum >= NSIG)
559             {
560               builtin_error ("bad signal number: %s", list->word->word);
561               result = EXECUTION_FAILURE;
562               list = list->next;
563               continue;
564             }
565
566           name = signal_name (signum);
567           if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
568             {
569               list = list->next;
570               continue;
571             }
572 #if defined (JOB_CONTROL)
573           /* POSIX.2 says that `kill -l signum' prints the signal name without
574              the `SIG' prefix. */
575           printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
576 #else
577           printf ("%s\n", name);
578 #endif
579         }
580       else
581         {
582           signum = decode_signal (list->word->word);
583           if (signum == NO_SIG)
584             {
585               builtin_error ("%s: not a signal specification", list->word->word);
586               result = EXECUTION_FAILURE;
587               list = list->next;
588               continue;
589             }
590           printf ("%ld\n", signum);
591         }
592       list = list->next;
593     }
594   return (result);
595 }
596
597 /* **************************************************************** */
598 /*                                                                  */
599 /*          Finding builtin commands and their functions            */
600 /*                                                                  */
601 /* **************************************************************** */
602
603 /* Perform a binary search and return the address of the builtin function
604    whose name is NAME.  If the function couldn't be found, or the builtin
605    is disabled or has no function associated with it, return NULL.
606    Return the address of the builtin.
607    DISABLED_OKAY means find it even if the builtin is disabled. */
608 struct builtin *
609 builtin_address_internal (name, disabled_okay)
610      char *name;
611      int disabled_okay;
612 {
613   int hi, lo, mid, j;
614
615   hi = num_shell_builtins - 1;
616   lo = 0;
617
618   while (lo <= hi)
619     {
620       mid = (lo + hi) / 2;
621
622       j = shell_builtins[mid].name[0] - name[0];
623
624       if (j == 0)
625         j = strcmp (shell_builtins[mid].name, name);
626
627       if (j == 0)
628         {
629           /* It must have a function pointer.  It must be enabled, or we
630              must have explicitly allowed disabled functions to be found,
631              and it must not have been deleted. */
632           if (shell_builtins[mid].function &&
633               ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
634               ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
635             return (&shell_builtins[mid]);
636           else
637             return ((struct builtin *)NULL);
638         }
639       if (j > 0)
640         hi = mid - 1;
641       else
642         lo = mid + 1;
643     }
644   return ((struct builtin *)NULL);
645 }
646
647 /* Return the pointer to the function implementing builtin command NAME. */
648 Function *
649 find_shell_builtin (name)
650      char *name;
651 {
652   current_builtin = builtin_address_internal (name, 0);
653   return (current_builtin ? current_builtin->function : (Function *)NULL);
654 }
655
656 /* Return the address of builtin with NAME, whether it is enabled or not. */
657 Function *
658 builtin_address (name)
659      char *name;
660 {
661   current_builtin = builtin_address_internal (name, 1);
662   return (current_builtin ? current_builtin->function : (Function *)NULL);
663 }
664
665 /* Return the function implementing the builtin NAME, but only if it is a
666    POSIX.2 special builtin. */
667 Function *
668 find_special_builtin (name)
669      char *name;
670 {
671   current_builtin = builtin_address_internal (name, 0);
672   return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
673                         current_builtin->function :
674                         (Function *)NULL);
675 }
676   
677 static int
678 shell_builtin_compare (sbp1, sbp2)
679      struct builtin *sbp1, *sbp2;
680 {
681   int result;
682
683   if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
684     result = strcmp (sbp1->name, sbp2->name);
685
686   return (result);
687 }
688
689 /* Sort the table of shell builtins so that the binary search will work
690    in find_shell_builtin. */
691 void
692 initialize_shell_builtins ()
693 {
694   qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
695     shell_builtin_compare);
696 }
697
698 /* **************************************************************** */
699 /*                                                                  */
700 /*       Functions for quoting strings to be re-read as input       */
701 /*                                                                  */
702 /* **************************************************************** */
703
704 /* Return a new string which is the single-quoted version of STRING.
705    Used by alias and trap, among others. */
706 char *
707 single_quote (string)
708      char *string;
709 {
710   register int c;
711   char *result, *r, *s;
712
713   result = (char *)xmalloc (3 + (4 * strlen (string)));
714   r = result;
715   *r++ = '\'';
716
717   for (s = string; s && (c = *s); s++)
718     {
719       *r++ = c;
720
721       if (c == '\'')
722         {
723           *r++ = '\\';  /* insert escaped single quote */
724           *r++ = '\'';
725           *r++ = '\'';  /* start new quoted string */
726         }
727     }
728
729   *r++ = '\'';
730   *r = '\0';
731
732   return (result);
733 }
734
735 /* Quote STRING using double quotes.  Return a new string. */
736 char *
737 double_quote (string)
738      char *string;
739 {
740   register int c;
741   char *result, *r, *s;
742
743   result = (char *)xmalloc (3 + (2 * strlen (string)));
744   r = result;
745   *r++ = '"';
746
747   for (s = string; s && (c = *s); s++)
748     {
749       switch (c)
750         {
751         case '"':
752         case '$':
753         case '`':
754         case '\\':
755           *r++ = '\\';
756         default:
757           *r++ = c;
758           break;
759         }
760     }
761
762   *r++ = '"';
763   *r = '\0';
764
765   return (result);
766 }
767
768 /* Quote special characters in STRING using backslashes.  Return a new
769    string. */
770 char *
771 backslash_quote (string)
772      char *string;
773 {
774   int c;
775   char *result, *r, *s;
776
777   result = xmalloc (2 * strlen (string) + 1);
778
779   for (r = result, s = string; s && (c = *s); s++)
780     {
781       switch (c)
782         {
783         case ' ': case '\t': case '\n':         /* IFS white space */
784         case '\'': case '"': case '\\':         /* quoting chars */
785         case '|': case '&': case ';':           /* shell metacharacters */
786         case '(': case ')': case '<': case '>':
787         case '!': case '{': case '}':           /* reserved words */
788         case '*': case '[': case '?': case ']': /* globbing chars */
789         case '^':
790         case '$': case '`':                     /* expansion chars */
791           *r++ = '\\';
792           *r++ = c;
793           break;
794         case '#':                               /* comment char */
795 #if 0
796         case '~':                               /* tilde expansion */
797 #endif
798           if (s == string)
799             *r++ = '\\';
800           /* FALLTHROUGH */
801         default:
802           *r++ = c;
803           break;
804         }
805     }
806
807   *r = '\0';
808   return (result);
809 }
810
811 int
812 contains_shell_metas (string)
813      char *string;
814 {
815   char *s;
816
817   for (s = string; s && *s; s++)
818     {
819       switch (*s)
820         {
821         case ' ': case '\t': case '\n':         /* IFS white space */
822         case '\'': case '"': case '\\':         /* quoting chars */
823         case '|': case '&': case ';':           /* shell metacharacters */
824         case '(': case ')': case '<': case '>':
825         case '!': case '{': case '}':           /* reserved words */
826         case '*': case '[': case '?': case ']': /* globbing chars */
827         case '^':
828         case '$': case '`':                     /* expansion chars */
829           return (1);
830         case '#':
831           if (s == string)                      /* comment char */
832             return (1);
833           /* FALLTHROUGH */
834         default:
835           break;
836         }
837     }
838
839   return (0);
840 }