This file is command.def, from which is created command.c. It implements the builtin "command" in Bash. Copyright (C) 1987-2004 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 2, 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, 59 Temple Place, Suite 330, Boston, MA 02111 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 #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../bashansi.h" #include "../shell.h" #include "../execute_cmd.h" #include "../flags.h" #include "bashgetopt.h" #include "common.h" #if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR extern size_t confstr __P((int, char *, size_t)); #endif extern int subshell_environment; static void restore_path __P((char *)); static char *get_standard_path __P((void)); /* Run the commands mentioned in LIST without paying attention to shell functions. */ int command_builtin (list) WORD_LIST *list; { int result, verbose, use_standard_path, opt; char *old_path, *standard_path; COMMAND *command; verbose = use_standard_path = 0; reset_internal_getopt (); while ((opt = internal_getopt (list, "pvV")) != -1) { switch (opt) { case 'p': use_standard_path = 1; break; case 'V': verbose = CDESC_SHORTDESC|CDESC_ABSPATH; /* look in common.h for constants */ break; case 'v': verbose = CDESC_REUSABLE; /* ditto */ break; default: builtin_usage (); return (EX_USAGE); } } list = loptend; if (list == 0) return (EXECUTION_SUCCESS); if (verbose) { int found, any_found; for (any_found = 0; list; list = list->next) { found = describe_command (list->word->word, verbose); if (found == 0 && verbose != CDESC_REUSABLE) sh_notfound (list->word->word); any_found += found; } return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE); } #if defined (RESTRICTED_SHELL) if (use_standard_path && restricted) { sh_restricted ("-p"); return (EXECUTION_FAILURE); } #endif 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. */ if (use_standard_path) { old_path = get_string_value ("PATH"); /* If old_path is NULL, $PATH is unset. If so, we want to make sure it's unset after this command completes. */ if (old_path) old_path = savestring (old_path); add_unwind_protect ((Function *)restore_path, old_path); standard_path = get_standard_path (); bind_variable ("PATH", standard_path ? standard_path : "", 0); FREE (standard_path); } #define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN) command = make_bare_simple_command (); command->value.Simple->words = (WORD_LIST *)copy_word_list (list); command->value.Simple->redirects = (REDIRECT *)NULL; command->flags |= COMMAND_BUILTIN_FLAGS; command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS; #if 0 /* This breaks for things like ( cd /tmp ; command z ababa ; echo next ) or $(command echo a ; command echo b;) or even { command echo a; command echo b; } & */ /* 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; } #endif 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; { if (var) { bind_variable ("PATH", var, 0); free (var); } else unbind_variable ("PATH"); } /* 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 (HAVE_CONFSTR) char *p; size_t len; len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0); if (len > 0) { p = (char *)xmalloc (len + 2); *p = '\0'; confstr (_CS_PATH, p, len); return (p); } else return (savestring (STANDARD_UTILS_PATH)); #else /* !_CS_PATH || !HAVE_CONFSTR */ # if defined (CS_PATH) return (savestring (CS_PATH)); # else return (savestring (STANDARD_UTILS_PATH)); # endif /* !CS_PATH */ #endif /* !_CS_PATH || !HAVE_CONFSTR */ }