source: trunk/essentials/app-shells/bash/builtins/command.def

Last change on this file was 3228, checked in by bird, 18 years ago

bash 3.1

File size: 5.7 KB
Line 
1This file is command.def, from which is created command.c.
2It implements the builtin "command" in Bash.
3
4Copyright (C) 1987-2004 Free Software Foundation, Inc.
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
8Bash is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with Bash; see the file COPYING. If not, write to the Free Software
20Foundation, 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 ...]
27Runs COMMAND with ARGS ignoring shell functions. If you have a shell
28function called `ls', and you wish to call the command `ls', you can
29say "command ls". If the -p option is given, a default value is used
30for PATH that is guaranteed to find all of the standard utilities. If
31the -V or -v option is given, a string is printed describing COMMAND.
32The -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#if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR
53extern size_t confstr __P((int, char *, size_t));
54#endif
55
56extern int subshell_environment;
57
58static void restore_path __P((char *));
59static char *get_standard_path __P((void));
60
61/* Run the commands mentioned in LIST without paying attention to shell
62 functions. */
63int
64command_builtin (list)
65 WORD_LIST *list;
66{
67 int result, verbose, use_standard_path, opt;
68 char *old_path, *standard_path;
69 COMMAND *command;
70
71 verbose = use_standard_path = 0;
72 reset_internal_getopt ();
73 while ((opt = internal_getopt (list, "pvV")) != -1)
74 {
75 switch (opt)
76 {
77 case 'p':
78 use_standard_path = 1;
79 break;
80 case 'V':
81 verbose = CDESC_SHORTDESC|CDESC_ABSPATH; /* look in common.h for constants */
82 break;
83 case 'v':
84 verbose = CDESC_REUSABLE; /* ditto */
85 break;
86 default:
87 builtin_usage ();
88 return (EX_USAGE);
89 }
90 }
91 list = loptend;
92
93 if (list == 0)
94 return (EXECUTION_SUCCESS);
95
96 if (verbose)
97 {
98 int found, any_found;
99
100 for (any_found = 0; list; list = list->next)
101 {
102 found = describe_command (list->word->word, verbose);
103
104 if (found == 0 && verbose != CDESC_REUSABLE)
105 sh_notfound (list->word->word);
106
107 any_found += found;
108 }
109 return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
110 }
111
112#if defined (RESTRICTED_SHELL)
113 if (use_standard_path && restricted)
114 {
115 sh_restricted ("-p");
116 return (EXECUTION_FAILURE);
117 }
118#endif
119
120 begin_unwind_frame ("command_builtin");
121
122 /* We don't want this to be reparsed (consider command echo 'foo &'), so
123 just make a simple_command structure and call execute_command with it. */
124 if (use_standard_path)
125 {
126 old_path = get_string_value ("PATH");
127 /* If old_path is NULL, $PATH is unset. If so, we want to make sure
128 it's unset after this command completes. */
129 if (old_path)
130 old_path = savestring (old_path);
131 add_unwind_protect ((Function *)restore_path, old_path);
132
133 standard_path = get_standard_path ();
134 bind_variable ("PATH", standard_path ? standard_path : "", 0);
135 FREE (standard_path);
136 }
137
138#define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN)
139
140 command = make_bare_simple_command ();
141 command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
142 command->value.Simple->redirects = (REDIRECT *)NULL;
143 command->flags |= COMMAND_BUILTIN_FLAGS;
144 command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS;
145#if 0
146 /* This breaks for things like ( cd /tmp ; command z ababa ; echo next )
147 or $(command echo a ; command echo b;) or even
148 { command echo a; command echo b; } & */
149 /* If we're in a subshell, see if we can get away without forking
150 again, since we've already forked to run this builtin. */
151 if (subshell_environment)
152 {
153 command->flags |= CMD_NO_FORK;
154 command->value.Simple->flags |= CMD_NO_FORK;
155 }
156#endif
157 add_unwind_protect ((char *)dispose_command, command);
158 result = execute_command (command);
159
160 run_unwind_frame ("command_builtin");
161
162 return (result);
163}
164
165/* Restore the value of the $PATH variable after replacing it when
166 executing `command -p'. */
167static void
168restore_path (var)
169 char *var;
170{
171 if (var)
172 {
173 bind_variable ("PATH", var, 0);
174 free (var);
175 }
176 else
177 unbind_variable ("PATH");
178}
179
180/* Return a value for PATH that is guaranteed to find all of the standard
181 utilities. This uses Posix.2 configuration variables, if present. It
182 uses a value defined in config.h as a last resort. */
183static char *
184get_standard_path ()
185{
186#if defined (_CS_PATH) && defined (HAVE_CONFSTR)
187 char *p;
188 size_t len;
189
190 len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0);
191 if (len > 0)
192 {
193 p = (char *)xmalloc (len + 2);
194 *p = '\0';
195 confstr (_CS_PATH, p, len);
196 return (p);
197 }
198 else
199 return (savestring (STANDARD_UTILS_PATH));
200#else /* !_CS_PATH || !HAVE_CONFSTR */
201# if defined (CS_PATH)
202 return (savestring (CS_PATH));
203# else
204 return (savestring (STANDARD_UTILS_PATH));
205# endif /* !CS_PATH */
206#endif /* !_CS_PATH || !HAVE_CONFSTR */
207}
Note: See TracBrowser for help on using the repository browser.