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