diff options
Diffstat (limited to 'builtins/command.def')
-rw-r--r-- | builtins/command.def | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/builtins/command.def b/builtins/command.def new file mode 100644 index 0000000..b84613e --- /dev/null +++ b/builtins/command.def @@ -0,0 +1,177 @@ +This file is command.def, from which is created command.c. +It implements the builtin "command" in Bash. + +Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. + +This file is part of GNU Bash, the Bourne Again SHell. + +Bash is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 1, or (at your option) any later +version. + +Bash is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License along +with Bash; see the file COPYING. If not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +$PRODUCES command.c + +$BUILTIN command +$FUNCTION command_builtin +$SHORT_DOC command [-pVv] [command [arg ...]] +Runs COMMAND with ARGS ignoring shell functions. If you have a shell +function called `ls', and you wish to call the command `ls', you can +say "command ls". If the -p option is given, a default value is used +for PATH that is guaranteed to find all of the standard utilities. If +the -V or -v option is given, a string is printed describing COMMAND. +The -V option produces a more verbose description. +$END + +#if defined (HAVE_STRING_H) +# include <string.h> +#else /* !HAVE_STRING_H */ +# include <strings.h> +#endif /* !HAVE_STRING_H */ + +#include "../shell.h" +#include "bashgetopt.h" + +extern int subshell_environment; + +static void restore_path (); +static char *get_standard_path (); + +/* Run the commands mentioned in LIST without paying attention to shell + functions. */ +int +command_builtin (list) + WORD_LIST *list; +{ + int result, verbose = 0, use_standard_path = 0, opt; + char *old_path; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "pvV")) != -1) + { + switch (opt) + { + case 'p': + use_standard_path = 1; + break; + case 'V': + verbose = 2; + break; + case 'v': + verbose = 4; + break; + + default: + report_bad_option (); + builtin_error ("usage: command [-pvV] [command [arg...]]"); + return (EX_USAGE); + } + } + list = loptend; + + if (!list) + return (EXECUTION_SUCCESS); + + if (verbose) + { + int found, any_found = 0; + + while (list) + { + + found = describe_command (list->word->word, verbose, 0); + + if (!found) + builtin_error ("%s: not found", list->word->word); + + any_found += found; + list = list->next; + } + return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE); + } + + begin_unwind_frame ("command_builtin"); + + /* We don't want this to be reparsed (consider command echo 'foo &'), so + just make a simple_command structure and call execute_command with it. */ + { + COMMAND *command; + + if (use_standard_path) + { + char *standard_path; + + old_path = get_string_value ("PATH"); + if (old_path) + old_path = savestring (old_path); + else + old_path = savestring (""); + add_unwind_protect ((Function *)restore_path, old_path); + + standard_path = get_standard_path (); + bind_variable ("PATH", standard_path); + free (standard_path); + } + command = make_bare_simple_command (); + command->value.Simple->words = (WORD_LIST *)copy_word_list (list); + command->value.Simple->redirects = (REDIRECT *)NULL; + command->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION); + command->value.Simple->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION); + /* If we're in a subshell, see if we can get away without forking + again, since we've already forked to run this builtin. */ + if (subshell_environment) + { + command->flags |= CMD_NO_FORK; + command->value.Simple->flags |= CMD_NO_FORK; + } + add_unwind_protect ((char *)dispose_command, command); + result = execute_command (command); + } + + run_unwind_frame ("command_builtin"); + + return (result); +} + +/* Restore the value of the $PATH variable after replacing it when + executing `command -p'. */ +static void +restore_path (var) + char *var; +{ + bind_variable ("PATH", var); + free (var); +} + +/* Return a value for PATH that is guaranteed to find all of the standard + utilities. This uses Posix.2 configuration variables, if present. It + uses a value defined in config.h as a last resort. */ +static char * +get_standard_path () +{ +#if defined (_CS_PATH) && !defined (hpux_7) && !defined (NetBSD) + char *p; + size_t len; + + len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0); + p = xmalloc ((int)len + 2); + *p = '\0'; + confstr (_CS_PATH, p, len); + return (p); +#else /* !_CSPATH || hpux_7 || NetBSD */ +# if defined (CS_PATH) + return (savestring (CS_PATH)); +# else + return (savestring (STANDARD_UTILS_PATH)); +# endif /* !CS_PATH */ +#endif /* !_CS_PATH || hpux_7 */ +} |