]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/command.def
Bash-4.3 patch 32
[thirdparty/bash.git] / builtins / command.def
1 This file is command.def, from which is created command.c.
2 It implements the builtin "command" in Bash.
3
4 Copyright (C) 1987-2009 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
20
21 $PRODUCES command.c
22
23 $BUILTIN command
24 $FUNCTION command_builtin
25 $SHORT_DOC command [-pVv] command [arg ...]
26 Execute a simple command or display information about commands.
27
28 Runs COMMAND with ARGS suppressing shell function lookup, or display
29 information about the specified COMMANDs. Can be used to invoke commands
30 on disk when a function with the same name exists.
31
32 Options:
33 -p use a default value for PATH that is guaranteed to find all of
34 the standard utilities
35 -v print a description of COMMAND similar to the `type' builtin
36 -V print a more verbose description of each COMMAND
37
38 Exit Status:
39 Returns exit status of COMMAND, or failure if COMMAND is not found.
40 $END
41
42 #include <config.h>
43
44 #if defined (HAVE_UNISTD_H)
45 # ifdef _MINIX
46 # include <sys/types.h>
47 # endif
48 # include <unistd.h>
49 #endif
50
51 #include "../bashansi.h"
52
53 #include "../shell.h"
54 #include "../execute_cmd.h"
55 #include "../flags.h"
56 #include "bashgetopt.h"
57 #include "common.h"
58
59 #if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR
60 extern size_t confstr __P((int, char *, size_t));
61 #endif
62
63 extern int subshell_environment;
64
65 static void restore_path __P((char *));
66 static char *get_standard_path __P((void));
67
68 /* Run the commands mentioned in LIST without paying attention to shell
69 functions. */
70 int
71 command_builtin (list)
72 WORD_LIST *list;
73 {
74 int result, verbose, use_standard_path, opt;
75 char *old_path, *standard_path;
76 COMMAND *command;
77
78 verbose = use_standard_path = 0;
79 reset_internal_getopt ();
80 while ((opt = internal_getopt (list, "pvV")) != -1)
81 {
82 switch (opt)
83 {
84 case 'p':
85 use_standard_path = 1;
86 break;
87 case 'V':
88 verbose = CDESC_SHORTDESC|CDESC_ABSPATH; /* look in common.h for constants */
89 break;
90 case 'v':
91 verbose = CDESC_REUSABLE; /* ditto */
92 break;
93 default:
94 builtin_usage ();
95 return (EX_USAGE);
96 }
97 }
98 list = loptend;
99
100 if (list == 0)
101 return (EXECUTION_SUCCESS);
102
103 #if defined (RESTRICTED_SHELL)
104 if (use_standard_path && restricted)
105 {
106 sh_restricted ("-p");
107 return (EXECUTION_FAILURE);
108 }
109 #endif
110
111 begin_unwind_frame ("command_builtin");
112
113 if (use_standard_path)
114 {
115 old_path = get_string_value ("PATH");
116 /* If old_path is NULL, $PATH is unset. If so, we want to make sure
117 it's unset after this command completes. */
118 if (old_path)
119 old_path = savestring (old_path);
120 add_unwind_protect ((Function *)restore_path, old_path);
121
122 standard_path = get_standard_path ();
123 bind_variable ("PATH", standard_path ? standard_path : "", 0);
124 stupidly_hack_special_variables ("PATH");
125 FREE (standard_path);
126 }
127
128 if (verbose)
129 {
130 int found, any_found;
131
132 for (any_found = 0; list; list = list->next)
133 {
134 found = describe_command (list->word->word, verbose);
135
136 if (found == 0 && verbose != CDESC_REUSABLE)
137 sh_notfound (list->word->word);
138
139 any_found += found;
140 }
141
142 run_unwind_frame ("command_builtin");
143 return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
144 }
145
146 #define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN)
147
148 /* We don't want this to be reparsed (consider command echo 'foo &'), so
149 just make a simple_command structure and call execute_command with it. */
150 command = make_bare_simple_command ();
151 command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
152 command->value.Simple->redirects = (REDIRECT *)NULL;
153 command->flags |= COMMAND_BUILTIN_FLAGS;
154 command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS;
155 #if 0
156 /* This breaks for things like ( cd /tmp ; command z ababa ; echo next )
157 or $(command echo a ; command echo b;) or even
158 { command echo a; command echo b; } & */
159 /* If we're in a subshell, see if we can get away without forking
160 again, since we've already forked to run this builtin. */
161 if (subshell_environment)
162 {
163 command->flags |= CMD_NO_FORK;
164 command->value.Simple->flags |= CMD_NO_FORK;
165 }
166 #endif
167 add_unwind_protect ((char *)dispose_command, command);
168 result = execute_command (command);
169
170 run_unwind_frame ("command_builtin");
171
172 return (result);
173 }
174
175 /* Restore the value of the $PATH variable after replacing it when
176 executing `command -p'. */
177 static void
178 restore_path (var)
179 char *var;
180 {
181 if (var)
182 {
183 bind_variable ("PATH", var, 0);
184 free (var);
185 }
186 else
187 unbind_variable ("PATH");
188
189 stupidly_hack_special_variables ("PATH");
190 }
191
192 /* Return a value for PATH that is guaranteed to find all of the standard
193 utilities. This uses Posix.2 configuration variables, if present. It
194 uses a value defined in config.h as a last resort. */
195 static char *
196 get_standard_path ()
197 {
198 #if defined (_CS_PATH) && defined (HAVE_CONFSTR)
199 char *p;
200 size_t len;
201
202 len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0);
203 if (len > 0)
204 {
205 p = (char *)xmalloc (len + 2);
206 *p = '\0';
207 confstr (_CS_PATH, p, len);
208 return (p);
209 }
210 else
211 return (savestring (STANDARD_UTILS_PATH));
212 #else /* !_CS_PATH || !HAVE_CONFSTR */
213 # if defined (CS_PATH)
214 return (savestring (CS_PATH));
215 # else
216 return (savestring (STANDARD_UTILS_PATH));
217 # endif /* !CS_PATH */
218 #endif /* !_CS_PATH || !HAVE_CONFSTR */
219 }