1 /* Copyright (C) 1987-2002 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)
42 #include "../bashansi.h"
48 #include "../builtins.h"
50 #include "../execute_cmd.h"
52 #include "bashgetopt.h"
55 #include <tilde/tilde.h>
58 # include "../bashhist.h"
65 extern int indirection_level, subshell_environment;
66 extern int line_number;
67 extern int last_command_exit_value;
68 extern int running_trap;
69 extern int posixly_correct;
70 extern char *this_command_name, *shell_name;
71 extern char *bash_getcwd_errstr;
73 /* Used by some builtins and the mainline code. */
74 sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL;
75 sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
77 /* **************************************************************** */
79 /* Error reporting, usage, and option processing */
81 /* **************************************************************** */
83 /* This is a lot like report_error (), but it is for shell builtins
84 instead of shell control structures, and it won't ever exit the
87 #if defined (PREFER_STDARG)
88 builtin_error (const char *format, ...)
90 builtin_error (format, va_alist)
98 name = get_name_for_error ();
99 fprintf (stderr, "%s: ", name);
101 if (interactive_shell == 0)
102 fprintf (stderr, "line %d: ", executing_line_number ());
104 if (this_command_name && *this_command_name)
105 fprintf (stderr, "%s: ", this_command_name);
107 SH_VA_START (args, format);
109 vfprintf (stderr, format, args);
111 fprintf (stderr, "\n");
114 /* Print a usage summary for the currently-executing builtin command. */
118 if (this_command_name && *this_command_name)
119 fprintf (stderr, "%s: usage: ", this_command_name);
120 fprintf (stderr, "%s\n", current_builtin->short_doc);
124 /* Return if LIST is NULL else barf and jump to top_level. Used by some
125 builtins that do not accept arguments. */
132 builtin_error ("too many arguments");
133 jump_to_top_level (DISCARD);
137 /* Check that no options were given to the currently-executing builtin,
138 and return 0 if there were options. */
143 reset_internal_getopt ();
144 if (internal_getopt (list, "") != -1)
156 builtin_error ("%s: option requires an argument", s);
163 builtin_error ("%s: numeric argument required", s);
170 builtin_error ("%s: not found", s);
173 /* Function called when one of the builtin commands detects an invalid
179 builtin_error ("%s: invalid option", s);
183 sh_invalidoptname (s)
186 builtin_error ("%s: invalid option name", s);
193 builtin_error ("`%s': not a valid identifier", s);
200 builtin_error ("%s: invalid number", s);
207 builtin_error ("%s: invalid signal specification", s);
214 builtin_error ("`%s': not a pid or valid job spec", s);
221 builtin_error ("%s: readonly variable", s);
229 builtin_error ("%s: %s out of range", s, desc ? desc : "argument");
231 builtin_error ("%s out of range", desc ? desc : "argument");
234 #if defined (JOB_CONTROL)
239 builtin_error ("%s: no such job", s);
247 builtin_error ("%s: no job control");
249 builtin_error ("no job control");
253 #if defined (RESTRICTED_SHELL)
259 builtin_error ("%s: restricted", s);
261 builtin_error ("restricted");
265 /* **************************************************************** */
267 /* Shell positional parameter manipulation */
269 /* **************************************************************** */
271 /* Convert a WORD_LIST into a C-style argv. Return the number of elements
272 in the list in *IP, if IP is non-null. A convenience function for
273 loadable builtins; also used by `test'. */
275 make_builtin_argv (list, ip)
281 argv = strvec_from_word_list (list, 0, 1, ip);
282 argv[0] = this_command_name;
286 /* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
287 non-zero, then discard whatever the existing arguments are, else
288 only discard the ones that are to be replaced. */
290 remember_args (list, destructive)
296 for (i = 1; i < 10; i++)
298 if ((destructive || list) && dollar_vars[i])
300 free (dollar_vars[i]);
301 dollar_vars[i] = (char *)NULL;
306 dollar_vars[i] = savestring (list->word->word);
311 /* If arguments remain, assign them to REST_OF_ARGS.
312 Note that copy_word_list (NULL) returns NULL, and
313 that dispose_words (NULL) does nothing. */
314 if (destructive || list)
316 dispose_words (rest_of_args);
317 rest_of_args = copy_word_list (list);
321 set_dollar_vars_changed ();
324 static int changed_dollar_vars;
326 /* Have the dollar variables been reset to new values since we last
329 dollar_vars_changed ()
331 return (changed_dollar_vars);
335 set_dollar_vars_unchanged ()
337 changed_dollar_vars = 0;
341 set_dollar_vars_changed ()
343 if (variable_context)
344 changed_dollar_vars |= ARGS_FUNC;
345 else if (this_shell_builtin == set_builtin)
346 changed_dollar_vars |= ARGS_SETBLTIN;
348 changed_dollar_vars |= ARGS_INVOC;
351 /* **************************************************************** */
353 /* Validating numeric input and arguments */
355 /* **************************************************************** */
357 /* Read a numeric arg for this_command_name, the name of the shell builtin
358 that wants it. LIST is the word list that the arg is to come from.
359 Accept only the numeric argument; report an error if other arguments
360 follow. If FATAL is true, call throw_to_top_level, which exits the
361 shell; if not, call jump_to_top_level (DISCARD), which aborts the
364 get_numeric_arg (list, fatal)
370 if (list && list->word && ISOPTION (list->word->word, '-'))
377 arg = list->word->word;
378 if (arg == 0 || (legal_number (arg, &count) == 0))
380 sh_neednumarg (list->word->word);
382 throw_to_top_level ();
384 jump_to_top_level (DISCARD);
386 no_args (list->next);
392 /* Get an eight-bit status value from LIST */
401 if (list && list->word && ISOPTION (list->word->word, '-'))
405 return (last_command_exit_value);
407 arg = list->word->word;
408 if (arg == 0 || legal_number (arg, &sval) == 0)
410 sh_neednumarg (list->word->word ? list->word->word : "`'");
413 no_args (list->next);
419 /* Return the octal number parsed from STRING, or -1 to indicate
420 that the string contained a bad number. */
428 while (*string && ISOCTAL (*string))
431 result = (result * 8) + (*string++ - '0');
436 if (digits == 0 || *string)
442 /* **************************************************************** */
444 /* Manipulating the current working directory */
446 /* **************************************************************** */
448 /* Return a consed string which is the current working directory.
449 FOR_WHOM is the name of the caller for error printing. */
450 char *the_current_working_directory = (char *)NULL;
453 get_working_directory (for_whom)
458 if (no_symbolic_links)
460 if (the_current_working_directory)
461 free (the_current_working_directory);
463 the_current_working_directory = (char *)NULL;
466 if (the_current_working_directory == 0)
468 the_current_working_directory = (char *)xmalloc (PATH_MAX);
469 the_current_working_directory[0] = '\0';
470 directory = getcwd (the_current_working_directory, PATH_MAX);
473 fprintf (stderr, "%s: could not get current directory: %s: %s\n",
474 (for_whom && *for_whom) ? for_whom : get_name_for_error (),
475 bash_getcwd_errstr, strerror (errno));
477 free (the_current_working_directory);
478 the_current_working_directory = (char *)NULL;
483 return (savestring (the_current_working_directory));
486 /* Make NAME our internal idea of the current working directory. */
488 set_working_directory (name)
491 FREE (the_current_working_directory);
492 the_current_working_directory = savestring (name);
495 /* **************************************************************** */
497 /* Job control support functions */
499 /* **************************************************************** */
501 #if defined (JOB_CONTROL)
503 get_job_by_name (name, flags)
507 register int i, wl, cl, match, job;
512 for (i = job_slots - 1; i >= 0; i--)
514 if (jobs[i] == 0 || ((flags & JM_STOPPED) && JOBSTATE(i) != JSTOPPED))
520 if (flags & JM_EXACT)
522 cl = strlen (p->command);
523 match = STREQN (p->command, name, cl);
525 else if (flags & JM_SUBSTRING)
526 match = strindex (p->command, name) != (char *)0;
528 match = STREQN (p->command, name, wl);
535 else if (flags & JM_FIRSTMATCH)
536 return i; /* return first match */
537 else if (job != NO_JOB)
539 if (this_shell_builtin)
540 builtin_error ("%s: ambiguous job spec", name);
542 report_error ("%s: ambiguous job spec", name);
548 while (p != jobs[i]->pipe);
554 /* Return the job spec found in LIST. */
563 return (current_job);
565 word = list->word->word;
568 return (current_job);
573 if (DIGIT (*word) && all_digits (word))
577 return (job >= job_slots ? NO_JOB : job - 1);
579 return (job > job_slots ? NO_JOB : job - 1);
589 return (current_job);
592 return (previous_job);
594 case '?': /* Substring search requested. */
595 jflags |= JM_SUBSTRING;
600 return get_job_by_name (word, jflags);
603 #endif /* JOB_CONTROL */
606 display_signal_list (list, forcecols)
610 register int i, column;
616 result = EXECUTION_SUCCESS;
619 for (i = 1, column = 0; i < NSIG; i++)
621 name = signal_name (i);
622 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
625 if (posixly_correct && !forcecols)
626 printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
629 printf ("%2d) %s", i, name);
641 if ((posixly_correct && !forcecols) || column != 0)
646 /* List individual signal names or numbers. */
649 if (legal_number (list->word->word, &lsignum))
651 /* This is specified by Posix.2 so that exit statuses can be
652 mapped into signal numbers. */
655 if (lsignum < 0 || lsignum >= NSIG)
657 sh_invalidsig (list->word->word);
658 result = EXECUTION_FAILURE;
664 name = signal_name (signum);
665 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
670 #if defined (JOB_CONTROL)
671 /* POSIX.2 says that `kill -l signum' prints the signal name without
673 printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
675 printf ("%s\n", name);
680 signum = decode_signal (list->word->word);
681 if (signum == NO_SIG)
683 sh_invalidsig (list->word->word);
684 result = EXECUTION_FAILURE;
688 printf ("%d\n", signum);
695 /* **************************************************************** */
697 /* Finding builtin commands and their functions */
699 /* **************************************************************** */
701 /* Perform a binary search and return the address of the builtin function
702 whose name is NAME. If the function couldn't be found, or the builtin
703 is disabled or has no function associated with it, return NULL.
704 Return the address of the builtin.
705 DISABLED_OKAY means find it even if the builtin is disabled. */
707 builtin_address_internal (name, disabled_okay)
713 hi = num_shell_builtins - 1;
720 j = shell_builtins[mid].name[0] - name[0];
723 j = strcmp (shell_builtins[mid].name, name);
727 /* It must have a function pointer. It must be enabled, or we
728 must have explicitly allowed disabled functions to be found,
729 and it must not have been deleted. */
730 if (shell_builtins[mid].function &&
731 ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
732 ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
733 return (&shell_builtins[mid]);
735 return ((struct builtin *)NULL);
742 return ((struct builtin *)NULL);
745 /* Return the pointer to the function implementing builtin command NAME. */
747 find_shell_builtin (name)
750 current_builtin = builtin_address_internal (name, 0);
751 return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
754 /* Return the address of builtin with NAME, whether it is enabled or not. */
756 builtin_address (name)
759 current_builtin = builtin_address_internal (name, 1);
760 return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
763 /* Return the function implementing the builtin NAME, but only if it is a
764 POSIX.2 special builtin. */
766 find_special_builtin (name)
769 current_builtin = builtin_address_internal (name, 0);
770 return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
771 current_builtin->function :
772 (sh_builtin_func_t *)NULL);
776 shell_builtin_compare (sbp1, sbp2)
777 struct builtin *sbp1, *sbp2;
781 if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
782 result = strcmp (sbp1->name, sbp2->name);
787 /* Sort the table of shell builtins so that the binary search will work
788 in find_shell_builtin. */
790 initialize_shell_builtins ()
792 qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
793 (QSFUNC *)shell_builtin_compare);