1/* command.c, created from command.def. */ 2#line 23 "command.def" 3 4#line 34 "command.def" 5 6#include <config.h> 7 8#if defined (HAVE_UNISTD_H) 9# ifdef _MINIX 10# include <sys/types.h> 11# endif 12# include <unistd.h> 13#endif 14 15#include "../bashansi.h" 16 17#include "../shell.h" 18#include "../execute_cmd.h" 19#include "../flags.h" 20#include "bashgetopt.h" 21#include "common.h" 22 23#if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR 24extern size_t confstr __P((int, char *, size_t)); 25#endif 26 27extern int subshell_environment; 28 29static void restore_path __P((char *)); 30static char *get_standard_path __P((void)); 31 32/* Run the commands mentioned in LIST without paying attention to shell 33 functions. */ 34int 35command_builtin (list) 36 WORD_LIST *list; 37{ 38 int result, verbose, use_standard_path, opt; 39 char *old_path, *standard_path; 40 COMMAND *command; 41 42 verbose = use_standard_path = 0; 43 reset_internal_getopt (); 44 while ((opt = internal_getopt (list, "pvV")) != -1) 45 { 46 switch (opt) 47 { 48 case 'p': 49 use_standard_path = 1; 50 break; 51 case 'V': 52 verbose = CDESC_SHORTDESC|CDESC_ABSPATH; /* look in common.h for constants */ 53 break; 54 case 'v': 55 verbose = CDESC_REUSABLE; /* ditto */ 56 break; 57 default: 58 builtin_usage (); 59 return (EX_USAGE); 60 } 61 } 62 list = loptend; 63 64 if (list == 0) 65 return (EXECUTION_SUCCESS); 66 67 if (verbose) 68 { 69 int found, any_found; 70 71 for (any_found = 0; list; list = list->next) 72 { 73 found = describe_command (list->word->word, verbose); 74 75 if (found == 0 && verbose != CDESC_REUSABLE) 76 sh_notfound (list->word->word); 77 78 any_found += found; 79 } 80 return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE); 81 } 82 83#if defined (RESTRICTED_SHELL) 84 if (use_standard_path && restricted) 85 { 86 sh_restricted ("-p"); 87 return (EXECUTION_FAILURE); 88 } 89#endif 90 91 begin_unwind_frame ("command_builtin"); 92 93 /* We don't want this to be reparsed (consider command echo 'foo &'), so 94 just make a simple_command structure and call execute_command with it. */ 95 if (use_standard_path) 96 { 97 old_path = get_string_value ("PATH"); 98 /* If old_path is NULL, $PATH is unset. If so, we want to make sure 99 it's unset after this command completes. */ 100 if (old_path) 101 old_path = savestring (old_path); 102 add_unwind_protect ((Function *)restore_path, old_path); 103 104 standard_path = get_standard_path (); 105 bind_variable ("PATH", standard_path ? standard_path : "", 0); 106 FREE (standard_path); 107 } 108 109#define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN) 110 111 command = make_bare_simple_command (); 112 command->value.Simple->words = (WORD_LIST *)copy_word_list (list); 113 command->value.Simple->redirects = (REDIRECT *)NULL; 114 command->flags |= COMMAND_BUILTIN_FLAGS; 115 command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS; 116#if 0 117 /* This breaks for things like ( cd /tmp ; command z ababa ; echo next ) 118 or $(command echo a ; command echo b;) or even 119 { command echo a; command echo b; } & */ 120 /* If we're in a subshell, see if we can get away without forking 121 again, since we've already forked to run this builtin. */ 122 if (subshell_environment) 123 { 124 command->flags |= CMD_NO_FORK; 125 command->value.Simple->flags |= CMD_NO_FORK; 126 } 127#endif 128 add_unwind_protect ((char *)dispose_command, command); 129 result = execute_command (command); 130 131 run_unwind_frame ("command_builtin"); 132 133 return (result); 134} 135 136/* Restore the value of the $PATH variable after replacing it when 137 executing `command -p'. */ 138static void 139restore_path (var) 140 char *var; 141{ 142 if (var) 143 { 144 bind_variable ("PATH", var, 0); 145 free (var); 146 } 147 else 148 unbind_variable ("PATH"); 149} 150 151/* Return a value for PATH that is guaranteed to find all of the standard 152 utilities. This uses Posix.2 configuration variables, if present. It 153 uses a value defined in config.h as a last resort. */ 154static char * 155get_standard_path () 156{ 157#if defined (_CS_PATH) && defined (HAVE_CONFSTR) 158 char *p; 159 size_t len; 160 161 len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0); 162 if (len > 0) 163 { 164 p = (char *)xmalloc (len + 2); 165 *p = '\0'; 166 confstr (_CS_PATH, p, len); 167 return (p); 168 } 169 else 170 return (savestring (STANDARD_UTILS_PATH)); 171#else /* !_CS_PATH || !HAVE_CONFSTR */ 172# if defined (CS_PATH) 173 return (savestring (CS_PATH)); 174# else 175 return (savestring (STANDARD_UTILS_PATH)); 176# endif /* !CS_PATH */ 177#endif /* !_CS_PATH || !HAVE_CONFSTR */ 178} 179