blob: 18452799484c45d3f1b591b8221bae0b95ea09a5 [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001This file is command.def, from which is created command.c.
2It implements the builtin "command" in Bash.
3
Jari Aalto31859422009-01-12 13:36:28 +00004Copyright (C) 1987-2009 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00005
6This file is part of GNU Bash, the Bourne Again SHell.
7
Jari Aalto31859422009-01-12 13:36:28 +00008Bash is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
Jari Aalto726f6381996-08-26 18:22:31 +000012
Jari Aalto31859422009-01-12 13:36:28 +000013Bash is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
Jari Aalto726f6381996-08-26 18:22:31 +000017
Jari Aalto31859422009-01-12 13:36:28 +000018You should have received a copy of the GNU General Public License
19along with Bash. If not, see <http://www.gnu.org/licenses/>.
Jari Aalto726f6381996-08-26 18:22:31 +000020
21$PRODUCES command.c
22
23$BUILTIN command
24$FUNCTION command_builtin
Jari Aaltoccc6cda1996-12-23 17:02:34 +000025$SHORT_DOC command [-pVv] command [arg ...]
Jari Aalto31859422009-01-12 13:36:28 +000026Execute a simple command or display information about commands.
27
28Runs COMMAND with ARGS suppressing shell function lookup, or display
29information about the specified COMMANDs. Can be used to invoke commands
30on disk when a function with the same name exists.
31
32Options:
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
38Exit Status:
39Returns exit status of COMMAND, or failure if COMMAND is not found.
Jari Aalto726f6381996-08-26 18:22:31 +000040$END
41
Jari Aaltoccc6cda1996-12-23 17:02:34 +000042#include <config.h>
43
44#if defined (HAVE_UNISTD_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000045# ifdef _MINIX
46# include <sys/types.h>
47# endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000048# include <unistd.h>
49#endif
50
51#include "../bashansi.h"
Jari Aalto726f6381996-08-26 18:22:31 +000052
53#include "../shell.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000054#include "../execute_cmd.h"
55#include "../flags.h"
Jari Aalto726f6381996-08-26 18:22:31 +000056#include "bashgetopt.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000057#include "common.h"
Jari Aalto726f6381996-08-26 18:22:31 +000058
Jari Aaltof73dda02001-11-13 17:56:06 +000059#if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR
60extern size_t confstr __P((int, char *, size_t));
61#endif
62
Jari Aalto726f6381996-08-26 18:22:31 +000063extern int subshell_environment;
64
Jari Aaltof73dda02001-11-13 17:56:06 +000065static void restore_path __P((char *));
66static char *get_standard_path __P((void));
Jari Aalto726f6381996-08-26 18:22:31 +000067
68/* Run the commands mentioned in LIST without paying attention to shell
69 functions. */
70int
71command_builtin (list)
72 WORD_LIST *list;
73{
Jari Aaltoccc6cda1996-12-23 17:02:34 +000074 int result, verbose, use_standard_path, opt;
75 char *old_path, *standard_path;
76 COMMAND *command;
77
78 verbose = use_standard_path = 0;
Jari Aalto726f6381996-08-26 18:22:31 +000079 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':
Jari Aalto95732b42005-12-07 14:08:12 +000088 verbose = CDESC_SHORTDESC|CDESC_ABSPATH; /* look in common.h for constants */
Jari Aalto726f6381996-08-26 18:22:31 +000089 break;
90 case 'v':
Jari Aalto7117c2d2002-07-17 14:10:11 +000091 verbose = CDESC_REUSABLE; /* ditto */
Jari Aalto726f6381996-08-26 18:22:31 +000092 break;
Jari Aalto726f6381996-08-26 18:22:31 +000093 default:
Jari Aaltoccc6cda1996-12-23 17:02:34 +000094 builtin_usage ();
Jari Aalto726f6381996-08-26 18:22:31 +000095 return (EX_USAGE);
96 }
97 }
98 list = loptend;
99
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000100 if (list == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000101 return (EXECUTION_SUCCESS);
102
Chet Ramey00018032011-11-21 20:51:19 -0500103#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
Jari Aalto726f6381996-08-26 18:22:31 +0000128 if (verbose)
129 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000130 int found, any_found;
Jari Aalto726f6381996-08-26 18:22:31 +0000131
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000132 for (any_found = 0; list; list = list->next)
Jari Aalto726f6381996-08-26 18:22:31 +0000133 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000134 found = describe_command (list->word->word, verbose);
Jari Aalto726f6381996-08-26 18:22:31 +0000135
Jari Aalto95732b42005-12-07 14:08:12 +0000136 if (found == 0 && verbose != CDESC_REUSABLE)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000137 sh_notfound (list->word->word);
Jari Aalto726f6381996-08-26 18:22:31 +0000138
139 any_found += found;
Jari Aalto726f6381996-08-26 18:22:31 +0000140 }
Chet Ramey00018032011-11-21 20:51:19 -0500141
142 run_unwind_frame ("command_builtin");
Jari Aalto726f6381996-08-26 18:22:31 +0000143 return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
144 }
145
Jari Aaltof73dda02001-11-13 17:56:06 +0000146#define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN)
147
Chet Ramey00018032011-11-21 20:51:19 -0500148 /* 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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000150 command = make_bare_simple_command ();
151 command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
152 command->value.Simple->redirects = (REDIRECT *)NULL;
Jari Aaltof73dda02001-11-13 17:56:06 +0000153 command->flags |= COMMAND_BUILTIN_FLAGS;
154 command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000155#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);
Jari Aalto726f6381996-08-26 18:22:31 +0000169
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'. */
177static void
178restore_path (var)
179 char *var;
180{
Jari Aaltod166f041997-06-05 14:59:13 +0000181 if (var)
182 {
Jari Aalto95732b42005-12-07 14:08:12 +0000183 bind_variable ("PATH", var, 0);
Jari Aaltod166f041997-06-05 14:59:13 +0000184 free (var);
185 }
186 else
187 unbind_variable ("PATH");
Chet Ramey00018032011-11-21 20:51:19 -0500188
189 stupidly_hack_special_variables ("PATH");
Jari Aalto726f6381996-08-26 18:22:31 +0000190}
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. */
195static char *
196get_standard_path ()
197{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000198#if defined (_CS_PATH) && defined (HAVE_CONFSTR)
Jari Aalto726f6381996-08-26 18:22:31 +0000199 char *p;
200 size_t len;
201
202 len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0);
Jari Aaltocce855b1998-04-17 19:52:44 +0000203 if (len > 0)
204 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000205 p = (char *)xmalloc (len + 2);
Jari Aaltocce855b1998-04-17 19:52:44 +0000206 *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 */
Jari Aalto726f6381996-08-26 18:22:31 +0000213# if defined (CS_PATH)
214 return (savestring (CS_PATH));
215# else
216 return (savestring (STANDARD_UTILS_PATH));
217# endif /* !CS_PATH */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000218#endif /* !_CS_PATH || !HAVE_CONFSTR */
Jari Aalto726f6381996-08-26 18:22:31 +0000219}