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 <sys/types.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"
49 #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 hashing_enabled;
63 extern int variable_context;
64 extern int posixly_correct;
65 extern char *this_command_name, *shell_name;
66 extern COMMAND *global_command;
67 extern HASH_TABLE *hashed_filenames;
68 extern char *bash_getcwd_errstr;
70 /* **************************************************************** */
72 /* Error reporting, usage, and option processing */
74 /* **************************************************************** */
76 /* This is a lot like report_error (), but it is for shell builtins
77 instead of shell control structures, and it won't ever exit the
79 #if defined (USE_VARARGS)
81 #if defined (PREFER_STDARG)
82 builtin_error (const char *format, ...)
84 builtin_error (format, va_alist)
92 name = get_name_for_error ();
93 fprintf (stderr, "%s: ", name);
95 if (this_command_name && *this_command_name)
96 fprintf (stderr, "%s: ", this_command_name);
98 #if defined (PREFER_STDARG)
99 va_start (args, format);
104 vfprintf (stderr, format, args);
106 fprintf (stderr, "\n");
108 #else /* !USE_VARARGS */
110 builtin_error (format, arg1, arg2, arg3, arg4, arg5)
111 char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
113 if (this_command_name && *this_command_name)
114 fprintf (stderr, "%s: ", this_command_name);
116 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
117 fprintf (stderr, "\n");
120 #endif /* !USE_VARARGS */
122 /* Print a usage summary for the currently-executing builtin command. */
126 if (this_command_name && *this_command_name)
127 fprintf (stderr, "%s: usage: ", this_command_name);
128 fprintf (stderr, "%s\n", current_builtin->short_doc);
132 /* Return if LIST is NULL else barf and jump to top_level. Used by some
133 builtins that do not accept arguments. */
140 builtin_error ("too many arguments");
141 jump_to_top_level (DISCARD);
145 /* Function called when one of the builtin commands detects a bad
151 builtin_error ("unknown option: %s", s);
154 /* Check that no options were given to the currently-executing builtin,
155 and return 0 if there were options. */
160 reset_internal_getopt ();
161 if (internal_getopt (list, "") != -1)
169 /* **************************************************************** */
171 /* Shell positional parameter manipulation */
173 /* **************************************************************** */
175 /* Convert a WORD_LIST into a C-style argv. Return the number of elements
176 in the list in *IP, if IP is non-null. A convenience function for
177 loadable builtins; also used by `test'. */
179 make_builtin_argv (list, ip)
185 argv = word_list_to_argv (list, 0, 1, ip);
186 argv[0] = this_command_name;
190 /* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
191 non-zero, then discard whatever the existing arguments are, else
192 only discard the ones that are to be replaced. */
194 remember_args (list, destructive)
200 for (i = 1; i < 10; i++)
202 if ((destructive || list) && dollar_vars[i])
204 free (dollar_vars[i]);
205 dollar_vars[i] = (char *)NULL;
210 dollar_vars[i] = savestring (list->word->word);
215 /* If arguments remain, assign them to REST_OF_ARGS.
216 Note that copy_word_list (NULL) returns NULL, and
217 that dispose_words (NULL) does nothing. */
218 if (destructive || list)
220 dispose_words (rest_of_args);
221 rest_of_args = copy_word_list (list);
225 set_dollar_vars_changed ();
228 /* **************************************************************** */
230 /* Pushing and Popping variable contexts */
232 /* **************************************************************** */
234 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
235 static int dollar_arg_stack_slots;
236 static int dollar_arg_stack_index;
249 kill_all_local_variables ();
253 /* Save the existing positional parameters on a stack. */
257 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
259 dollar_arg_stack = (WORD_LIST **)
260 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
261 * sizeof (WORD_LIST **));
263 dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
264 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
267 /* Restore the positional parameters from our stack. */
271 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
274 remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
275 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
276 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
280 dispose_saved_dollar_vars ()
282 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
285 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
286 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
289 static int changed_dollar_vars;
291 /* Have the dollar variables been reset to new values since we last
294 dollar_vars_changed ()
296 return (changed_dollar_vars);
300 set_dollar_vars_unchanged ()
302 changed_dollar_vars = 0;
306 set_dollar_vars_changed ()
308 changed_dollar_vars = 1;
311 /* **************************************************************** */
313 /* Validating numeric input and arguments */
315 /* **************************************************************** */
317 /* Read a numeric arg for this_command_name, the name of the shell builtin
318 that wants it. LIST is the word list that the arg is to come from.
319 Accept only the numeric argument; report an error if other arguments
322 get_numeric_arg (list)
331 arg = list->word->word;
332 if (!arg || (legal_number (arg, &count) == 0))
334 builtin_error ("bad non-numeric arg `%s'", list->word->word);
335 throw_to_top_level ();
337 no_args (list->next);
342 /* Return the octal number parsed from STRING, or -1 to indicate
343 that the string contained a bad number. */
351 while (*string && *string >= '0' && *string < '8')
354 result = (result * 8) + *string++ - '0';
357 if (!digits || result > 0777 || *string)
363 /* **************************************************************** */
365 /* Command name hashing */
367 /* **************************************************************** */
369 /* Return the full pathname that FILENAME hashes to. If FILENAME
370 is hashed, but (data->flags & HASH_CHKDOT) is non-zero, check
371 ./FILENAME and return that if it is executable. */
373 find_hashed_filename (filename)
376 register BUCKET_CONTENTS *item;
377 char *path, *dotted_filename, *tail;
380 if (hashing_enabled == 0)
381 return ((char *)NULL);
383 item = find_hash_item (filename, hashed_filenames);
386 return ((char *)NULL);
388 /* If this filename is hashed, but `.' comes before it in the path,
389 see if ./filename is executable. If the hashed value is not an
390 absolute pathname, see if ./`hashed-value' exists. */
391 path = pathdata(item)->path;
392 if (pathdata(item)->flags & (HASH_CHKDOT|HASH_RELPATH))
394 tail = (pathdata(item)->flags & HASH_RELPATH) ? path : filename;
395 dotted_filename = xmalloc (3 + strlen (tail));
396 dotted_filename[0] = '.'; dotted_filename[1] = '/';
397 strcpy (dotted_filename + 2, tail);
399 if (executable_file (dotted_filename))
400 return (dotted_filename);
402 free (dotted_filename);
405 if (pathdata(item)->flags & HASH_RELPATH)
406 return ((char *)NULL);
409 /* Watch out. If this file was hashed to "./filename", and
410 "./filename" is not executable, then return NULL. */
412 /* Since we already know "./filename" is not executable, what
413 we're really interested in is whether or not the `path'
414 portion of the hashed filename is equivalent to the current
415 directory, but only if it starts with a `.'. (This catches
416 ./. and so on.) same_file () tests general Unix file
417 equivalence -- same device and inode. */
421 tail = (char *)strrchr (path, '/');
426 same = same_file (".", path, (struct stat *)NULL, (struct stat *)NULL);
430 return same ? (char *)NULL : path;
437 /* **************************************************************** */
439 /* Manipulating the current working directory */
441 /* **************************************************************** */
443 /* Return a consed string which is the current working directory.
444 FOR_WHOM is the name of the caller for error printing. */
445 char *the_current_working_directory = (char *)NULL;
448 get_working_directory (for_whom)
453 if (no_symbolic_links)
455 if (the_current_working_directory)
456 free (the_current_working_directory);
458 the_current_working_directory = (char *)NULL;
461 if (the_current_working_directory == 0)
463 the_current_working_directory = xmalloc (PATH_MAX);
464 the_current_working_directory[0] = '\0';
465 directory = getcwd (the_current_working_directory, PATH_MAX);
468 fprintf (stderr, "%s: could not get current directory: %s\n",
469 (for_whom && *for_whom) ? for_whom : get_name_for_error (),
470 the_current_working_directory[0]
471 ? the_current_working_directory
472 : bash_getcwd_errstr);
474 free (the_current_working_directory);
475 the_current_working_directory = (char *)NULL;
480 return (savestring (the_current_working_directory));
483 /* Make NAME our internal idea of the current working directory. */
485 set_working_directory (name)
488 FREE (the_current_working_directory);
489 the_current_working_directory = savestring (name);
492 /* **************************************************************** */
494 /* Job control support functions */
496 /* **************************************************************** */
498 #if defined (JOB_CONTROL)
499 /* Return the job spec found in LIST. */
508 return (current_job);
510 word = list->word->word;
513 return (current_job);
518 if (digit (*word) && all_digits (word))
530 return (current_job);
533 return (previous_job);
535 case '?': /* Substring search requested. */
546 for (i = 0; i < job_slots; i++)
554 if ((substring && strindex (p->command, word)) ||
555 (STREQN (p->command, word, wl)))
558 builtin_error ("ambigious job spec: %s", word);
566 while (p != jobs[i]->pipe);
573 #endif /* JOB_CONTROL */
576 display_signal_list (list, forcecols)
580 register int i, column;
585 result = EXECUTION_SUCCESS;
588 for (i = 1, column = 0; i < NSIG; i++)
590 name = signal_name (i);
591 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
594 if (posixly_correct && !forcecols)
595 printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
598 printf ("%2d) %s", i, name);
610 if ((posixly_correct && !forcecols) || column != 0)
615 /* List individual signal names or numbers. */
618 if (legal_number (list->word->word, &signum))
620 /* This is specified by Posix.2 so that exit statuses can be
621 mapped into signal numbers. */
624 if (signum < 0 || signum >= NSIG)
626 builtin_error ("bad signal number: %s", list->word->word);
627 result = EXECUTION_FAILURE;
632 name = signal_name (signum);
633 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
638 printf ("%s\n", name);
642 signum = decode_signal (list->word->word);
643 if (signum == NO_SIG)
645 builtin_error ("%s: not a signal specification", list->word->word);
646 result = EXECUTION_FAILURE;
650 printf ("%ld\n", signum);
657 /* **************************************************************** */
659 /* Finding builtin commands and their functions */
661 /* **************************************************************** */
663 /* Perform a binary search and return the address of the builtin function
664 whose name is NAME. If the function couldn't be found, or the builtin
665 is disabled or has no function associated with it, return NULL.
666 Return the address of the builtin.
667 DISABLED_OKAY means find it even if the builtin is disabled. */
669 builtin_address_internal (name, disabled_okay)
675 hi = num_shell_builtins - 1;
682 j = shell_builtins[mid].name[0] - name[0];
685 j = strcmp (shell_builtins[mid].name, name);
689 /* It must have a function pointer. It must be enabled, or we
690 must have explicitly allowed disabled functions to be found,
691 and it must not have been deleted. */
692 if (shell_builtins[mid].function &&
693 ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
694 ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
695 return (&shell_builtins[mid]);
697 return ((struct builtin *)NULL);
704 return ((struct builtin *)NULL);
707 /* Return the pointer to the function implementing builtin command NAME. */
709 find_shell_builtin (name)
712 current_builtin = builtin_address_internal (name, 0);
713 return (current_builtin ? current_builtin->function : (Function *)NULL);
716 /* Return the address of builtin with NAME, whether it is enabled or not. */
718 builtin_address (name)
721 current_builtin = builtin_address_internal (name, 1);
722 return (current_builtin ? current_builtin->function : (Function *)NULL);
725 /* Return the function implementing the builtin NAME, but only if it is a
726 POSIX.2 special builtin. */
728 find_special_builtin (name)
731 current_builtin = builtin_address_internal (name, 0);
732 return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
733 current_builtin->function :
738 shell_builtin_compare (sbp1, sbp2)
739 struct builtin *sbp1, *sbp2;
743 if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
744 result = strcmp (sbp1->name, sbp2->name);
749 /* Sort the table of shell builtins so that the binary search will work
750 in find_shell_builtin. */
752 initialize_shell_builtins ()
754 qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
755 shell_builtin_compare);
758 /* **************************************************************** */
760 /* Functions for quoting strings to be re-read as input */
762 /* **************************************************************** */
764 /* Return a new string which is the single-quoted version of STRING.
765 Used by alias and trap, among others. */
767 single_quote (string)
771 char *result, *r, *s;
773 result = (char *)xmalloc (3 + (4 * strlen (string)));
777 for (s = string; s && (c = *s); s++)
783 *r++ = '\\'; /* insert escaped single quote */
785 *r++ = '\''; /* start new quoted string */
795 /* Quote STRING using double quotes. Return a new string. */
797 double_quote (string)
801 char *result, *r, *s;
803 result = (char *)xmalloc (3 + (2 * strlen (string)));
807 for (s = string; s && (c = *s); s++)
828 /* Quote special characters in STRING using backslashes. Return a new
831 backslash_quote (string)
835 char *result, *r, *s;
837 result = xmalloc (2 * strlen (string) + 1);
839 for (r = result, s = string; s && (c = *s); s++)
843 case ' ': case '\t': case '\n': /* IFS white space */
844 case '\'': case '"': case '\\': /* quoting chars */
845 case '|': case '&': case ';': /* shell metacharacters */
846 case '(': case ')': case '<': case '>':
847 case '!': case '{': case '}': /* reserved words */
848 case '*': case '[': case '?': case ']': /* globbing chars */
850 case '$': case '`': /* expansion chars */
854 case '#': /* comment char */
869 contains_shell_metas (string)
874 for (s = string; s && *s; s++)
878 case ' ': case '\t': case '\n': /* IFS white space */
879 case '\'': case '"': case '\\': /* quoting chars */
880 case '|': case '&': case ';': /* shell metacharacters */
881 case '(': case ')': case '<': case '>':
882 case '!': case '{': case '}': /* reserved words */
883 case '*': case '[': case '?': case ']': /* globbing chars */
885 case '$': case '`': /* expansion chars */
888 if (s == string) /* comment char */