| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | This file is command.def, from which is created command.c. | 
					
						
							|  |  |  | It implements the builtin "command" in Bash. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | Copyright (C) 1987-2009 Free Software Foundation, Inc. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | This file is part of GNU Bash, the Bourne Again SHell. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | 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 3 of the License, or | 
					
						
							|  |  |  | (at your option) any later version. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | along with Bash.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | $PRODUCES command.c | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $BUILTIN command | 
					
						
							|  |  |  | $FUNCTION command_builtin | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | $SHORT_DOC command [-pVv] command [arg ...] | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | Execute a simple command or display information about commands. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Runs COMMAND with ARGS suppressing  shell function lookup, or display | 
					
						
							|  |  |  | information about the specified COMMANDs.  Can be used to invoke commands | 
					
						
							|  |  |  | on disk when a function with the same name exists. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Options: | 
					
						
							|  |  |  |   -p	use a default value for PATH that is guaranteed to find all of | 
					
						
							|  |  |  | 	the standard utilities | 
					
						
							|  |  |  |   -v	print a description of COMMAND similar to the `type' builtin | 
					
						
							|  |  |  |   -V	print a more verbose description of each COMMAND | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Exit Status: | 
					
						
							|  |  |  | Returns exit status of COMMAND, or failure if COMMAND is not found. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | $END | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #include <config.h> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_UNISTD_H) | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #  ifdef _MINIX | 
					
						
							|  |  |  | #    include <sys/types.h> | 
					
						
							|  |  |  | #  endif | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #  include <unistd.h> | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "../bashansi.h" | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "../shell.h" | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #include "../execute_cmd.h" | 
					
						
							|  |  |  | #include "../flags.h" | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | #include "bashgetopt.h" | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #include "common.h" | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR | 
					
						
							|  |  |  | extern size_t confstr __P((int, char *, size_t)); | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | extern int subshell_environment; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | static void restore_path __P((char *)); | 
					
						
							|  |  |  | static char *get_standard_path __P((void)); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Run the commands mentioned in LIST without paying attention to shell | 
					
						
							|  |  |  |    functions. */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | command_builtin (list) | 
					
						
							|  |  |  |      WORD_LIST *list; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   int result, verbose, use_standard_path, opt; | 
					
						
							|  |  |  |   char *old_path, *standard_path; | 
					
						
							|  |  |  |   COMMAND *command; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   verbose = use_standard_path = 0; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |   reset_internal_getopt (); | 
					
						
							|  |  |  |   while ((opt = internal_getopt (list, "pvV")) != -1) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       switch (opt) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case 'p': | 
					
						
							|  |  |  | 	  use_standard_path = 1; | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | 	case 'V': | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | 	  verbose = CDESC_SHORTDESC|CDESC_ABSPATH;	/* look in common.h for constants */ | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 	  break; | 
					
						
							|  |  |  | 	case 'v': | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | 	  verbose = CDESC_REUSABLE;	/* ditto */ | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 	  break; | 
					
						
							|  |  |  | 	default: | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	  builtin_usage (); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 	  return (EX_USAGE); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   list = loptend; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   if (list == 0) | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |     return (EXECUTION_SUCCESS); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #if defined (RESTRICTED_SHELL) | 
					
						
							|  |  |  |   if (use_standard_path && restricted) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |       sh_restricted ("-p"); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       return (EXECUTION_FAILURE); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |   begin_unwind_frame ("command_builtin"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   if (use_standard_path) | 
					
						
							|  |  |  |     {       | 
					
						
							|  |  |  |       old_path = get_string_value ("PATH"); | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |       /* If old_path is NULL, $PATH is unset.  If so, we want to make sure | 
					
						
							|  |  |  | 	 it's unset after this command completes. */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       if (old_path) | 
					
						
							|  |  |  | 	old_path = savestring (old_path); | 
					
						
							|  |  |  |       add_unwind_protect ((Function *)restore_path, old_path); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       standard_path = get_standard_path (); | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |       bind_variable ("PATH", standard_path ? standard_path : "", 0); | 
					
						
							| 
									
										
										
										
											2011-11-21 20:51:19 -05:00
										 |  |  |       stupidly_hack_special_variables ("PATH"); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       FREE (standard_path); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-21 20:51:19 -05:00
										 |  |  |   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; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       run_unwind_frame ("command_builtin"); | 
					
						
							|  |  |  |       return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-21 20:51:19 -05:00
										 |  |  |   /* 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. */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   command = make_bare_simple_command (); | 
					
						
							|  |  |  |   command->value.Simple->words = (WORD_LIST *)copy_word_list (list); | 
					
						
							|  |  |  |   command->value.Simple->redirects = (REDIRECT *)NULL; | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   command->flags |= COMMAND_BUILTIN_FLAGS; | 
					
						
							|  |  |  |   command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #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); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |   if (var) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |       bind_variable ("PATH", var, 0); | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |       free (var); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     unbind_variable ("PATH"); | 
					
						
							| 
									
										
										
										
											2011-11-21 20:51:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   stupidly_hack_special_variables ("PATH"); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* 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 () | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #if defined (_CS_PATH) && defined (HAVE_CONFSTR) | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |   char *p; | 
					
						
							|  |  |  |   size_t len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0); | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  |   if (len > 0) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |       p = (char *)xmalloc (len + 2); | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  |       *p = '\0'; | 
					
						
							|  |  |  |       confstr (_CS_PATH, p, len); | 
					
						
							|  |  |  |       return (p); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     return (savestring (STANDARD_UTILS_PATH)); | 
					
						
							|  |  |  | #else /* !_CS_PATH || !HAVE_CONFSTR  */ | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | #  if defined (CS_PATH) | 
					
						
							|  |  |  |   return (savestring (CS_PATH)); | 
					
						
							|  |  |  | #  else | 
					
						
							|  |  |  |   return (savestring (STANDARD_UTILS_PATH)); | 
					
						
							|  |  |  | #  endif /* !CS_PATH */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif /* !_CS_PATH || !HAVE_CONFSTR */ | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | } |