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 <chartypes.h>
30 #include "../bashtypes.h"
31 #include "posixstat.h"
36 #if defined (PREFER_STDARG)
39 # if defined (PREFER_VARARGS)
44 #include "../bashansi.h"
50 #include "../builtins.h"
52 #include "../execute_cmd.h"
54 #include "bashgetopt.h"
57 #include <tilde/tilde.h>
60 # include "../bashhist.h"
67 extern int no_symbolic_links;
68 extern int indirection_level, startup_state, subshell_environment;
69 extern int line_number;
70 extern int last_command_exit_value;
71 extern int running_trap;
72 extern int posixly_correct;
73 extern char *this_command_name, *shell_name;
74 extern char *bash_getcwd_errstr;
76 /* Used by some builtins and the mainline code. */
77 sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL;
78 sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
80 /* **************************************************************** */
82 /* Error reporting, usage, and option processing */
84 /* **************************************************************** */
86 /* This is a lot like report_error (), but it is for shell builtins
87 instead of shell control structures, and it won't ever exit the
89 #if defined (USE_VARARGS)
91 #if defined (PREFER_STDARG)
92 builtin_error (const char *format, ...)
94 builtin_error (format, va_alist)
102 name = get_name_for_error ();
103 fprintf (stderr, "%s: ", name);
105 if (this_command_name && *this_command_name)
106 fprintf (stderr, "%s: ", this_command_name);
108 #if defined (PREFER_STDARG)
109 va_start (args, format);
114 vfprintf (stderr, format, args);
116 fprintf (stderr, "\n");
118 #else /* !USE_VARARGS */
120 builtin_error (format, arg1, arg2, arg3, arg4, arg5)
121 char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
123 if (this_command_name && *this_command_name)
124 fprintf (stderr, "%s: ", this_command_name);
126 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
127 fprintf (stderr, "\n");
130 #endif /* !USE_VARARGS */
132 /* Print a usage summary for the currently-executing builtin command. */
136 if (this_command_name && *this_command_name)
137 fprintf (stderr, "%s: usage: ", this_command_name);
138 fprintf (stderr, "%s\n", current_builtin->short_doc);
142 /* Return if LIST is NULL else barf and jump to top_level. Used by some
143 builtins that do not accept arguments. */
150 builtin_error ("too many arguments");
151 jump_to_top_level (DISCARD);
155 /* Function called when one of the builtin commands detects a bad
161 builtin_error ("unknown option: %s", s);
164 /* Check that no options were given to the currently-executing builtin,
165 and return 0 if there were options. */
170 reset_internal_getopt ();
171 if (internal_getopt (list, "") != -1)
179 /* **************************************************************** */
181 /* Shell positional parameter manipulation */
183 /* **************************************************************** */
185 /* Convert a WORD_LIST into a C-style argv. Return the number of elements
186 in the list in *IP, if IP is non-null. A convenience function for
187 loadable builtins; also used by `test'. */
189 make_builtin_argv (list, ip)
195 argv = word_list_to_argv (list, 0, 1, ip);
196 argv[0] = this_command_name;
200 /* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
201 non-zero, then discard whatever the existing arguments are, else
202 only discard the ones that are to be replaced. */
204 remember_args (list, destructive)
210 for (i = 1; i < 10; i++)
212 if ((destructive || list) && dollar_vars[i])
214 free (dollar_vars[i]);
215 dollar_vars[i] = (char *)NULL;
220 dollar_vars[i] = savestring (list->word->word);
225 /* If arguments remain, assign them to REST_OF_ARGS.
226 Note that copy_word_list (NULL) returns NULL, and
227 that dispose_words (NULL) does nothing. */
228 if (destructive || list)
230 dispose_words (rest_of_args);
231 rest_of_args = copy_word_list (list);
235 set_dollar_vars_changed ();
238 /* **************************************************************** */
240 /* Pushing and Popping variable contexts */
242 /* **************************************************************** */
244 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
245 static int dollar_arg_stack_slots;
246 static int dollar_arg_stack_index;
259 kill_all_local_variables ();
263 /* Save the existing positional parameters on a stack. */
267 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
269 dollar_arg_stack = (WORD_LIST **)
270 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
271 * sizeof (WORD_LIST **));
273 dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
274 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
277 /* Restore the positional parameters from our stack. */
281 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
284 remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
285 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
286 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
290 dispose_saved_dollar_vars ()
292 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
295 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
296 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
299 static int changed_dollar_vars;
301 /* Have the dollar variables been reset to new values since we last
304 dollar_vars_changed ()
306 return (changed_dollar_vars);
310 set_dollar_vars_unchanged ()
312 changed_dollar_vars = 0;
316 set_dollar_vars_changed ()
318 changed_dollar_vars = 1;
321 /* **************************************************************** */
323 /* Validating numeric input and arguments */
325 /* **************************************************************** */
327 /* Read a numeric arg for this_command_name, the name of the shell builtin
328 that wants it. LIST is the word list that the arg is to come from.
329 Accept only the numeric argument; report an error if other arguments
330 follow. If FATAL is true, call throw_to_top_level, which exits the
331 shell; if not, call jump_to_top_level (DISCARD), which aborts the
334 get_numeric_arg (list, fatal)
344 arg = list->word->word;
345 if (!arg || (legal_number (arg, &count) == 0))
347 builtin_error ("bad non-numeric arg `%s'", list->word->word);
349 throw_to_top_level ();
351 jump_to_top_level (DISCARD);
353 no_args (list->next);
359 /* Get an eight-bit status value from LIST */
368 arg = list->word->word;
369 if (arg == 0 || legal_number (arg, &sval) == 0)
371 builtin_error ("bad non-numeric arg `%s'", list->word->word);
374 no_args (list->next);
380 /* Return the octal number parsed from STRING, or -1 to indicate
381 that the string contained a bad number. */
389 while (*string && ISOCTAL (*string))
392 result = (result * 8) + (*string++ - '0');
397 if (digits == 0 || *string)
403 /* **************************************************************** */
405 /* Manipulating the current working directory */
407 /* **************************************************************** */
409 /* Return a consed string which is the current working directory.
410 FOR_WHOM is the name of the caller for error printing. */
411 char *the_current_working_directory = (char *)NULL;
414 get_working_directory (for_whom)
419 if (no_symbolic_links)
421 if (the_current_working_directory)
422 free (the_current_working_directory);
424 the_current_working_directory = (char *)NULL;
427 if (the_current_working_directory == 0)
429 the_current_working_directory = (char *)xmalloc (PATH_MAX);
430 the_current_working_directory[0] = '\0';
431 directory = getcwd (the_current_working_directory, PATH_MAX);
434 fprintf (stderr, "%s: could not get current directory: %s: %s\n",
435 (for_whom && *for_whom) ? for_whom : get_name_for_error (),
436 bash_getcwd_errstr, strerror (errno));
438 free (the_current_working_directory);
439 the_current_working_directory = (char *)NULL;
444 return (savestring (the_current_working_directory));
447 /* Make NAME our internal idea of the current working directory. */
449 set_working_directory (name)
452 FREE (the_current_working_directory);
453 the_current_working_directory = savestring (name);
456 /* **************************************************************** */
458 /* Job control support functions */
460 /* **************************************************************** */
462 #if defined (JOB_CONTROL)
463 /* Return the job spec found in LIST. */
469 int job, substring_search;
472 return (current_job);
474 word = list->word->word;
477 return (current_job);
482 if (DIGIT (*word) && all_digits (word))
485 return (job >= job_slots ? NO_JOB : job - 1);
488 substring_search = 0;
494 return (current_job);
497 return (previous_job);
499 case '?': /* Substring search requested. */
510 for (i = 0; i < job_slots; i++)
518 if ((substring_search && strindex (p->command, word)) ||
519 (STREQN (p->command, word, wl)))
523 builtin_error ("ambigious job spec: %s", word);
532 while (p != jobs[i]->pipe);
539 #endif /* JOB_CONTROL */
542 display_signal_list (list, forcecols)
546 register int i, column;
551 result = EXECUTION_SUCCESS;
554 for (i = 1, column = 0; i < NSIG; i++)
556 name = signal_name (i);
557 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
560 if (posixly_correct && !forcecols)
561 printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
564 printf ("%2d) %s", i, name);
576 if ((posixly_correct && !forcecols) || column != 0)
581 /* List individual signal names or numbers. */
584 if (legal_number (list->word->word, &signum))
586 /* This is specified by Posix.2 so that exit statuses can be
587 mapped into signal numbers. */
590 if (signum < 0 || signum >= NSIG)
592 builtin_error ("bad signal number: %s", list->word->word);
593 result = EXECUTION_FAILURE;
598 name = signal_name (signum);
599 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
604 #if defined (JOB_CONTROL)
605 /* POSIX.2 says that `kill -l signum' prints the signal name without
607 printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
609 printf ("%s\n", name);
614 signum = decode_signal (list->word->word);
615 if (signum == NO_SIG)
617 builtin_error ("%s: not a signal specification", list->word->word);
618 result = EXECUTION_FAILURE;
622 printf ("%ld\n", signum);
629 /* **************************************************************** */
631 /* Finding builtin commands and their functions */
633 /* **************************************************************** */
635 /* Perform a binary search and return the address of the builtin function
636 whose name is NAME. If the function couldn't be found, or the builtin
637 is disabled or has no function associated with it, return NULL.
638 Return the address of the builtin.
639 DISABLED_OKAY means find it even if the builtin is disabled. */
641 builtin_address_internal (name, disabled_okay)
647 hi = num_shell_builtins - 1;
654 j = shell_builtins[mid].name[0] - name[0];
657 j = strcmp (shell_builtins[mid].name, name);
661 /* It must have a function pointer. It must be enabled, or we
662 must have explicitly allowed disabled functions to be found,
663 and it must not have been deleted. */
664 if (shell_builtins[mid].function &&
665 ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
666 ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
667 return (&shell_builtins[mid]);
669 return ((struct builtin *)NULL);
676 return ((struct builtin *)NULL);
679 /* Return the pointer to the function implementing builtin command NAME. */
681 find_shell_builtin (name)
684 current_builtin = builtin_address_internal (name, 0);
685 return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
688 /* Return the address of builtin with NAME, whether it is enabled or not. */
690 builtin_address (name)
693 current_builtin = builtin_address_internal (name, 1);
694 return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
697 /* Return the function implementing the builtin NAME, but only if it is a
698 POSIX.2 special builtin. */
700 find_special_builtin (name)
703 current_builtin = builtin_address_internal (name, 0);
704 return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
705 current_builtin->function :
706 (sh_builtin_func_t *)NULL);
710 shell_builtin_compare (sbp1, sbp2)
711 struct builtin *sbp1, *sbp2;
715 if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
716 result = strcmp (sbp1->name, sbp2->name);
721 /* Sort the table of shell builtins so that the binary search will work
722 in find_shell_builtin. */
724 initialize_shell_builtins ()
726 qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
727 (QSFUNC *)shell_builtin_compare);