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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #if defined (HAVE_UNISTD_H)
26 #include "../bashtypes.h"
27 #include "../posixstat.h"
30 #if defined (PREFER_STDARG)
33 # if defined (PREFER_VARARGS)
38 #include "../bashansi.h"
41 #include "../maxpath.h"
44 #include "../builtins.h"
46 #include "../execute_cmd.h"
48 #include "bashgetopt.h"
51 #include <tilde/tilde.h>
54 # include "../bashhist.h"
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;
68 /* Used by some builtins and the mainline code. */
69 Function *last_shell_builtin = (Function *)NULL;
70 Function *this_shell_builtin = (Function *)NULL;
72 /* **************************************************************** */
74 /* Error reporting, usage, and option processing */
76 /* **************************************************************** */
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
81 #if defined (USE_VARARGS)
83 #if defined (PREFER_STDARG)
84 builtin_error (const char *format, ...)
86 builtin_error (format, va_alist)
94 name = get_name_for_error ();
95 fprintf (stderr, "%s: ", name);
97 if (this_command_name && *this_command_name)
98 fprintf (stderr, "%s: ", this_command_name);
100 #if defined (PREFER_STDARG)
101 va_start (args, format);
106 vfprintf (stderr, format, args);
108 fprintf (stderr, "\n");
110 #else /* !USE_VARARGS */
112 builtin_error (format, arg1, arg2, arg3, arg4, arg5)
113 char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
115 if (this_command_name && *this_command_name)
116 fprintf (stderr, "%s: ", this_command_name);
118 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
119 fprintf (stderr, "\n");
122 #endif /* !USE_VARARGS */
124 /* Print a usage summary for the currently-executing builtin command. */
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);
134 /* Return if LIST is NULL else barf and jump to top_level. Used by some
135 builtins that do not accept arguments. */
142 builtin_error ("too many arguments");
143 jump_to_top_level (DISCARD);
147 /* Function called when one of the builtin commands detects a bad
153 builtin_error ("unknown option: %s", s);
156 /* Check that no options were given to the currently-executing builtin,
157 and return 0 if there were options. */
162 reset_internal_getopt ();
163 if (internal_getopt (list, "") != -1)
171 /* **************************************************************** */
173 /* Shell positional parameter manipulation */
175 /* **************************************************************** */
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'. */
181 make_builtin_argv (list, ip)
187 argv = word_list_to_argv (list, 0, 1, ip);
188 argv[0] = this_command_name;
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. */
196 remember_args (list, destructive)
202 for (i = 1; i < 10; i++)
204 if ((destructive || list) && dollar_vars[i])
206 free (dollar_vars[i]);
207 dollar_vars[i] = (char *)NULL;
212 dollar_vars[i] = savestring (list->word->word);
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)
222 dispose_words (rest_of_args);
223 rest_of_args = copy_word_list (list);
227 set_dollar_vars_changed ();
230 /* **************************************************************** */
232 /* Pushing and Popping variable contexts */
234 /* **************************************************************** */
236 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
237 static int dollar_arg_stack_slots;
238 static int dollar_arg_stack_index;
251 kill_all_local_variables ();
255 /* Save the existing positional parameters on a stack. */
259 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
261 dollar_arg_stack = (WORD_LIST **)
262 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
263 * sizeof (WORD_LIST **));
265 dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
266 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
269 /* Restore the positional parameters from our stack. */
273 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
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;
282 dispose_saved_dollar_vars ()
284 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
287 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
288 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
291 static int changed_dollar_vars;
293 /* Have the dollar variables been reset to new values since we last
296 dollar_vars_changed ()
298 return (changed_dollar_vars);
302 set_dollar_vars_unchanged ()
304 changed_dollar_vars = 0;
308 set_dollar_vars_changed ()
310 changed_dollar_vars = 1;
313 /* **************************************************************** */
315 /* Validating numeric input and arguments */
317 /* **************************************************************** */
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
326 get_numeric_arg (list, fatal)
336 arg = list->word->word;
337 if (!arg || (legal_number (arg, &count) == 0))
339 builtin_error ("bad non-numeric arg `%s'", list->word->word);
341 throw_to_top_level ();
343 jump_to_top_level (DISCARD);
345 no_args (list->next);
350 /* Return the octal number parsed from STRING, or -1 to indicate
351 that the string contained a bad number. */
359 while (*string && *string >= '0' && *string < '8')
362 result = (result * 8) + *string++ - '0';
365 if (!digits || result > 0777 || *string)
371 /* **************************************************************** */
373 /* Manipulating the current working directory */
375 /* **************************************************************** */
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;
382 get_working_directory (for_whom)
387 if (no_symbolic_links)
389 if (the_current_working_directory)
390 free (the_current_working_directory);
392 the_current_working_directory = (char *)NULL;
395 if (the_current_working_directory == 0)
397 the_current_working_directory = xmalloc (PATH_MAX);
398 the_current_working_directory[0] = '\0';
399 directory = getcwd (the_current_working_directory, PATH_MAX);
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);
408 free (the_current_working_directory);
409 the_current_working_directory = (char *)NULL;
414 return (savestring (the_current_working_directory));
417 /* Make NAME our internal idea of the current working directory. */
419 set_working_directory (name)
422 FREE (the_current_working_directory);
423 the_current_working_directory = savestring (name);
426 /* **************************************************************** */
428 /* Job control support functions */
430 /* **************************************************************** */
432 #if defined (JOB_CONTROL)
433 /* Return the job spec found in LIST. */
442 return (current_job);
444 word = list->word->word;
447 return (current_job);
452 if (digit (*word) && all_digits (word))
464 return (current_job);
467 return (previous_job);
469 case '?': /* Substring search requested. */
480 for (i = 0; i < job_slots; i++)
488 if ((substring && strindex (p->command, word)) ||
489 (STREQN (p->command, word, wl)))
492 builtin_error ("ambigious job spec: %s", word);
500 while (p != jobs[i]->pipe);
507 #endif /* JOB_CONTROL */
510 display_signal_list (list, forcecols)
514 register int i, column;
519 result = EXECUTION_SUCCESS;
522 for (i = 1, column = 0; i < NSIG; i++)
524 name = signal_name (i);
525 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
528 if (posixly_correct && !forcecols)
529 printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
532 printf ("%2d) %s", i, name);
544 if ((posixly_correct && !forcecols) || column != 0)
549 /* List individual signal names or numbers. */
552 if (legal_number (list->word->word, &signum))
554 /* This is specified by Posix.2 so that exit statuses can be
555 mapped into signal numbers. */
558 if (signum < 0 || signum >= NSIG)
560 builtin_error ("bad signal number: %s", list->word->word);
561 result = EXECUTION_FAILURE;
566 name = signal_name (signum);
567 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
572 #if defined (JOB_CONTROL)
573 /* POSIX.2 says that `kill -l signum' prints the signal name without
575 printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
577 printf ("%s\n", name);
582 signum = decode_signal (list->word->word);
583 if (signum == NO_SIG)
585 builtin_error ("%s: not a signal specification", list->word->word);
586 result = EXECUTION_FAILURE;
590 printf ("%ld\n", signum);
597 /* **************************************************************** */
599 /* Finding builtin commands and their functions */
601 /* **************************************************************** */
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. */
609 builtin_address_internal (name, disabled_okay)
615 hi = num_shell_builtins - 1;
622 j = shell_builtins[mid].name[0] - name[0];
625 j = strcmp (shell_builtins[mid].name, name);
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]);
637 return ((struct builtin *)NULL);
644 return ((struct builtin *)NULL);
647 /* Return the pointer to the function implementing builtin command NAME. */
649 find_shell_builtin (name)
652 current_builtin = builtin_address_internal (name, 0);
653 return (current_builtin ? current_builtin->function : (Function *)NULL);
656 /* Return the address of builtin with NAME, whether it is enabled or not. */
658 builtin_address (name)
661 current_builtin = builtin_address_internal (name, 1);
662 return (current_builtin ? current_builtin->function : (Function *)NULL);
665 /* Return the function implementing the builtin NAME, but only if it is a
666 POSIX.2 special builtin. */
668 find_special_builtin (name)
671 current_builtin = builtin_address_internal (name, 0);
672 return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
673 current_builtin->function :
678 shell_builtin_compare (sbp1, sbp2)
679 struct builtin *sbp1, *sbp2;
683 if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
684 result = strcmp (sbp1->name, sbp2->name);
689 /* Sort the table of shell builtins so that the binary search will work
690 in find_shell_builtin. */
692 initialize_shell_builtins ()
694 qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
695 shell_builtin_compare);
698 /* **************************************************************** */
700 /* Functions for quoting strings to be re-read as input */
702 /* **************************************************************** */
704 /* Return a new string which is the single-quoted version of STRING.
705 Used by alias and trap, among others. */
707 single_quote (string)
711 char *result, *r, *s;
713 result = (char *)xmalloc (3 + (4 * strlen (string)));
717 for (s = string; s && (c = *s); s++)
723 *r++ = '\\'; /* insert escaped single quote */
725 *r++ = '\''; /* start new quoted string */
735 /* Quote STRING using double quotes. Return a new string. */
737 double_quote (string)
741 char *result, *r, *s;
743 result = (char *)xmalloc (3 + (2 * strlen (string)));
747 for (s = string; s && (c = *s); s++)
768 /* Quote special characters in STRING using backslashes. Return a new
771 backslash_quote (string)
775 char *result, *r, *s;
777 result = xmalloc (2 * strlen (string) + 1);
779 for (r = result, s = string; s && (c = *s); s++)
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 */
790 case '$': case '`': /* expansion chars */
794 case '#': /* comment char */
796 case '~': /* tilde expansion */
812 contains_shell_metas (string)
817 for (s = string; s && *s; s++)
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 */
828 case '$': case '`': /* expansion chars */
831 if (s == string) /* comment char */