1 /* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
3 This file is part of GNU Bash, the Bourne Again SHell.
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 2, or (at your option) any later
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
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, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
21 #if defined (HAVE_UNISTD_H)
23 # include <sys/types.h>
29 #include "../bashtypes.h"
30 #include "posixstat.h"
35 #if defined (PREFER_STDARG)
38 # if defined (PREFER_VARARGS)
43 #include "../bashansi.h"
49 #include "../builtins.h"
51 #include "../execute_cmd.h"
53 #include "bashgetopt.h"
56 #include <tilde/tilde.h>
59 # include "../bashhist.h"
67 typedef int QSFUNC (const void *, const void *);
69 typedef int QSFUNC ();
72 extern int no_symbolic_links, interactive, interactive_shell;
73 extern int indirection_level, startup_state, subshell_environment;
74 extern int line_number;
75 extern int last_command_exit_value;
76 extern int running_trap;
77 extern int variable_context;
78 extern int posixly_correct;
79 extern char *this_command_name, *shell_name;
80 extern COMMAND *global_command;
81 extern char *bash_getcwd_errstr;
83 /* Used by some builtins and the mainline code. */
84 Function *last_shell_builtin = (Function *)NULL;
85 Function *this_shell_builtin = (Function *)NULL;
87 /* **************************************************************** */
89 /* Error reporting, usage, and option processing */
91 /* **************************************************************** */
93 /* This is a lot like report_error (), but it is for shell builtins
94 instead of shell control structures, and it won't ever exit the
96 #if defined (USE_VARARGS)
98 #if defined (PREFER_STDARG)
99 builtin_error (const char *format, ...)
101 builtin_error (format, va_alist)
109 name = get_name_for_error ();
110 fprintf (stderr, "%s: ", name);
112 if (this_command_name && *this_command_name)
113 fprintf (stderr, "%s: ", this_command_name);
115 #if defined (PREFER_STDARG)
116 va_start (args, format);
121 vfprintf (stderr, format, args);
123 fprintf (stderr, "\n");
125 #else /* !USE_VARARGS */
127 builtin_error (format, arg1, arg2, arg3, arg4, arg5)
128 char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
130 if (this_command_name && *this_command_name)
131 fprintf (stderr, "%s: ", this_command_name);
133 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
134 fprintf (stderr, "\n");
137 #endif /* !USE_VARARGS */
139 /* Print a usage summary for the currently-executing builtin command. */
143 if (this_command_name && *this_command_name)
144 fprintf (stderr, "%s: usage: ", this_command_name);
145 fprintf (stderr, "%s\n", current_builtin->short_doc);
149 /* Return if LIST is NULL else barf and jump to top_level. Used by some
150 builtins that do not accept arguments. */
157 builtin_error ("too many arguments");
158 jump_to_top_level (DISCARD);
162 /* Function called when one of the builtin commands detects a bad
168 builtin_error ("unknown option: %s", s);
171 /* Check that no options were given to the currently-executing builtin,
172 and return 0 if there were options. */
177 reset_internal_getopt ();
178 if (internal_getopt (list, "") != -1)
186 /* **************************************************************** */
188 /* Shell positional parameter manipulation */
190 /* **************************************************************** */
192 /* Convert a WORD_LIST into a C-style argv. Return the number of elements
193 in the list in *IP, if IP is non-null. A convenience function for
194 loadable builtins; also used by `test'. */
196 make_builtin_argv (list, ip)
202 argv = word_list_to_argv (list, 0, 1, ip);
203 argv[0] = this_command_name;
207 /* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
208 non-zero, then discard whatever the existing arguments are, else
209 only discard the ones that are to be replaced. */
211 remember_args (list, destructive)
217 for (i = 1; i < 10; i++)
219 if ((destructive || list) && dollar_vars[i])
221 free (dollar_vars[i]);
222 dollar_vars[i] = (char *)NULL;
227 dollar_vars[i] = savestring (list->word->word);
232 /* If arguments remain, assign them to REST_OF_ARGS.
233 Note that copy_word_list (NULL) returns NULL, and
234 that dispose_words (NULL) does nothing. */
235 if (destructive || list)
237 dispose_words (rest_of_args);
238 rest_of_args = copy_word_list (list);
242 set_dollar_vars_changed ();
245 /* **************************************************************** */
247 /* Pushing and Popping variable contexts */
249 /* **************************************************************** */
251 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
252 static int dollar_arg_stack_slots;
253 static int dollar_arg_stack_index;
266 kill_all_local_variables ();
270 /* Save the existing positional parameters on a stack. */
274 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
276 dollar_arg_stack = (WORD_LIST **)
277 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
278 * sizeof (WORD_LIST **));
280 dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
281 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
284 /* Restore the positional parameters from our stack. */
288 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
291 remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
292 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
293 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
297 dispose_saved_dollar_vars ()
299 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
302 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
303 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
306 static int changed_dollar_vars;
308 /* Have the dollar variables been reset to new values since we last
311 dollar_vars_changed ()
313 return (changed_dollar_vars);
317 set_dollar_vars_unchanged ()
319 changed_dollar_vars = 0;
323 set_dollar_vars_changed ()
325 changed_dollar_vars = 1;
328 /* **************************************************************** */
330 /* Validating numeric input and arguments */
332 /* **************************************************************** */
334 /* Read a numeric arg for this_command_name, the name of the shell builtin
335 that wants it. LIST is the word list that the arg is to come from.
336 Accept only the numeric argument; report an error if other arguments
337 follow. If FATAL is true, call throw_to_top_level, which exits the
338 shell; if not, call jump_to_top_level (DISCARD), which aborts the
341 get_numeric_arg (list, fatal)
351 arg = list->word->word;
352 if (!arg || (legal_number (arg, &count) == 0))
354 builtin_error ("bad non-numeric arg `%s'", list->word->word);
356 throw_to_top_level ();
358 jump_to_top_level (DISCARD);
360 no_args (list->next);
365 /* Return the octal number parsed from STRING, or -1 to indicate
366 that the string contained a bad number. */
374 while (*string && *string >= '0' && *string < '8')
377 result = (result * 8) + *string++ - '0';
380 if (!digits || result > 0777 || *string)
386 /* **************************************************************** */
388 /* Manipulating the current working directory */
390 /* **************************************************************** */
392 /* Return a consed string which is the current working directory.
393 FOR_WHOM is the name of the caller for error printing. */
394 char *the_current_working_directory = (char *)NULL;
397 get_working_directory (for_whom)
402 if (no_symbolic_links)
404 if (the_current_working_directory)
405 free (the_current_working_directory);
407 the_current_working_directory = (char *)NULL;
410 if (the_current_working_directory == 0)
412 the_current_working_directory = xmalloc (PATH_MAX);
413 the_current_working_directory[0] = '\0';
414 directory = getcwd (the_current_working_directory, PATH_MAX);
417 fprintf (stderr, "%s: could not get current directory: %s: %s\n",
418 (for_whom && *for_whom) ? for_whom : get_name_for_error (),
419 the_current_working_directory[0]
420 ? the_current_working_directory
421 : bash_getcwd_errstr,
424 free (the_current_working_directory);
425 the_current_working_directory = (char *)NULL;
430 return (savestring (the_current_working_directory));
433 /* Make NAME our internal idea of the current working directory. */
435 set_working_directory (name)
438 FREE (the_current_working_directory);
439 the_current_working_directory = savestring (name);
442 /* **************************************************************** */
444 /* Job control support functions */
446 /* **************************************************************** */
448 #if defined (JOB_CONTROL)
449 /* Return the job spec found in LIST. */
458 return (current_job);
460 word = list->word->word;
463 return (current_job);
468 if (digit (*word) && all_digits (word))
471 return (job >= job_slots ? NO_JOB : job - 1);
480 return (current_job);
483 return (previous_job);
485 case '?': /* Substring search requested. */
496 for (i = 0; i < job_slots; i++)
504 if ((substring && strindex (p->command, word)) ||
505 (STREQN (p->command, word, wl)))
508 builtin_error ("ambigious job spec: %s", word);
516 while (p != jobs[i]->pipe);
523 #endif /* JOB_CONTROL */
526 display_signal_list (list, forcecols)
530 register int i, column;
535 result = EXECUTION_SUCCESS;
538 for (i = 1, column = 0; i < NSIG; i++)
540 name = signal_name (i);
541 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
544 if (posixly_correct && !forcecols)
545 printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
548 printf ("%2d) %s", i, name);
560 if ((posixly_correct && !forcecols) || column != 0)
565 /* List individual signal names or numbers. */
568 if (legal_number (list->word->word, &signum))
570 /* This is specified by Posix.2 so that exit statuses can be
571 mapped into signal numbers. */
574 if (signum < 0 || signum >= NSIG)
576 builtin_error ("bad signal number: %s", list->word->word);
577 result = EXECUTION_FAILURE;
582 name = signal_name (signum);
583 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
588 #if defined (JOB_CONTROL)
589 /* POSIX.2 says that `kill -l signum' prints the signal name without
591 printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
593 printf ("%s\n", name);
598 signum = decode_signal (list->word->word);
599 if (signum == NO_SIG)
601 builtin_error ("%s: not a signal specification", list->word->word);
602 result = EXECUTION_FAILURE;
606 printf ("%ld\n", signum);
613 /* **************************************************************** */
615 /* Finding builtin commands and their functions */
617 /* **************************************************************** */
619 /* Perform a binary search and return the address of the builtin function
620 whose name is NAME. If the function couldn't be found, or the builtin
621 is disabled or has no function associated with it, return NULL.
622 Return the address of the builtin.
623 DISABLED_OKAY means find it even if the builtin is disabled. */
625 builtin_address_internal (name, disabled_okay)
631 hi = num_shell_builtins - 1;
638 j = shell_builtins[mid].name[0] - name[0];
641 j = strcmp (shell_builtins[mid].name, name);
645 /* It must have a function pointer. It must be enabled, or we
646 must have explicitly allowed disabled functions to be found,
647 and it must not have been deleted. */
648 if (shell_builtins[mid].function &&
649 ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
650 ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
651 return (&shell_builtins[mid]);
653 return ((struct builtin *)NULL);
660 return ((struct builtin *)NULL);
663 /* Return the pointer to the function implementing builtin command NAME. */
665 find_shell_builtin (name)
668 current_builtin = builtin_address_internal (name, 0);
669 return (current_builtin ? current_builtin->function : (Function *)NULL);
672 /* Return the address of builtin with NAME, whether it is enabled or not. */
674 builtin_address (name)
677 current_builtin = builtin_address_internal (name, 1);
678 return (current_builtin ? current_builtin->function : (Function *)NULL);
681 /* Return the function implementing the builtin NAME, but only if it is a
682 POSIX.2 special builtin. */
684 find_special_builtin (name)
687 current_builtin = builtin_address_internal (name, 0);
688 return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
689 current_builtin->function :
694 shell_builtin_compare (sbp1, sbp2)
695 struct builtin *sbp1, *sbp2;
699 if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
700 result = strcmp (sbp1->name, sbp2->name);
705 /* Sort the table of shell builtins so that the binary search will work
706 in find_shell_builtin. */
708 initialize_shell_builtins ()
710 qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
711 (QSFUNC *)shell_builtin_compare);
714 /* **************************************************************** */
716 /* Functions for quoting strings to be re-read as input */
718 /* **************************************************************** */
720 /* Return a new string which is the single-quoted version of STRING.
721 Used by alias and trap, among others. */
723 single_quote (string)
727 char *result, *r, *s;
729 result = (char *)xmalloc (3 + (4 * strlen (string)));
733 for (s = string; s && (c = *s); s++)
739 *r++ = '\\'; /* insert escaped single quote */
741 *r++ = '\''; /* start new quoted string */
751 /* Quote STRING using double quotes. Return a new string. */
753 double_quote (string)
757 char *result, *r, *s;
759 result = (char *)xmalloc (3 + (2 * strlen (string)));
763 for (s = string; s && (c = *s); s++)
785 /* Remove backslashes that are quoting characters that are special between
786 double quotes. Return a new string. */
788 un_double_quote (string)
791 register int c, pass_next;
792 char *result, *r, *s;
794 r = result = xmalloc (strlen (string) + 1);
796 for (pass_next = 0, s = string; s && (c = *s); s++)
804 if (c == '\\' && strchr (slashify_in_quotes, s[1]))
816 /* Quote special characters in STRING using backslashes. Return a new
819 backslash_quote (string)
823 char *result, *r, *s;
825 result = xmalloc (2 * strlen (string) + 1);
827 for (r = result, s = string; s && (c = *s); s++)
831 case ' ': case '\t': case '\n': /* IFS white space */
832 case '\'': case '"': case '\\': /* quoting chars */
833 case '|': case '&': case ';': /* shell metacharacters */
834 case '(': case ')': case '<': case '>':
835 case '!': case '{': case '}': /* reserved words */
836 case '*': case '[': case '?': case ']': /* globbing chars */
838 case '$': case '`': /* expansion chars */
843 case '~': /* tilde expansion */
844 if (s == string || s[-1] == '=' || s[-1] == ':')
849 case '#': /* comment char */
863 #if defined (PROMPT_STRING_DECODE)
864 /* Quote characters that get special treatment when in double quotes in STRING
865 using backslashes. Return a new string. */
867 backslash_quote_for_double_quotes (string)
871 char *result, *r, *s;
873 result = xmalloc (2 * strlen (string) + 1);
875 for (r = result, s = string; s && (c = *s); s++)
896 #endif /* PROMPT_STRING_DECODE */
899 contains_shell_metas (string)
904 for (s = string; s && *s; s++)
908 case ' ': case '\t': case '\n': /* IFS white space */
909 case '\'': case '"': case '\\': /* quoting chars */
910 case '|': case '&': case ';': /* shell metacharacters */
911 case '(': case ')': case '<': case '>':
912 case '!': case '{': case '}': /* reserved words */
913 case '*': case '[': case '?': case ']': /* globbing chars */
915 case '$': case '`': /* expansion chars */
917 case '~': /* tilde expansion */
918 if (s == string || s[-1] == '=' || s[-1] == ':')
921 if (s == string) /* comment char */