Imported from ../bash-4.0-rc1.tar.gz.
[platform/upstream/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 (verbose)
104     {
105       int found, any_found;
106
107       for (any_found = 0; list; list = list->next)
108         {
109           found = describe_command (list->word->word, verbose);
110
111           if (found == 0 && verbose != CDESC_REUSABLE)
112             sh_notfound (list->word->word);
113
114           any_found += found;
115         }
116       return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
117     }
118
119 #if defined (RESTRICTED_SHELL)
120   if (use_standard_path && restricted)
121     {
122       sh_restricted ("-p");
123       return (EXECUTION_FAILURE);
124     }
125 #endif
126
127   begin_unwind_frame ("command_builtin");
128
129   /* We don't want this to be reparsed (consider command echo 'foo &'), so
130      just make a simple_command structure and call execute_command with it. */
131   if (use_standard_path)
132     {      
133       old_path = get_string_value ("PATH");
134       /* If old_path is NULL, $PATH is unset.  If so, we want to make sure
135          it's unset after this command completes. */
136       if (old_path)
137         old_path = savestring (old_path);
138       add_unwind_protect ((Function *)restore_path, old_path);
139
140       standard_path = get_standard_path ();
141       bind_variable ("PATH", standard_path ? standard_path : "", 0);
142       FREE (standard_path);
143     }
144
145 #define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN)
146
147   command = make_bare_simple_command ();
148   command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
149   command->value.Simple->redirects = (REDIRECT *)NULL;
150   command->flags |= COMMAND_BUILTIN_FLAGS;
151   command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS;
152 #if 0
153   /* This breaks for things like ( cd /tmp ; command z ababa ; echo next )
154      or $(command echo a ; command echo b;) or even
155      { command echo a; command echo b; } & */
156   /* If we're in a subshell, see if we can get away without forking
157      again, since we've already forked to run this builtin. */
158   if (subshell_environment)
159     {
160       command->flags |= CMD_NO_FORK;
161       command->value.Simple->flags |= CMD_NO_FORK;
162     }
163 #endif
164   add_unwind_protect ((char *)dispose_command, command);
165   result = execute_command (command);
166
167   run_unwind_frame ("command_builtin");
168
169   return (result);
170 }
171
172 /* Restore the value of the $PATH variable after replacing it when
173    executing `command -p'. */
174 static void
175 restore_path (var)
176      char *var;
177 {
178   if (var)
179     {
180       bind_variable ("PATH", var, 0);
181       free (var);
182     }
183   else
184     unbind_variable ("PATH");
185 }
186
187 /* Return a value for PATH that is guaranteed to find all of the standard
188    utilities.  This uses Posix.2 configuration variables, if present.  It
189    uses a value defined in config.h as a last resort. */
190 static char *
191 get_standard_path ()
192 {
193 #if defined (_CS_PATH) && defined (HAVE_CONFSTR)
194   char *p;
195   size_t len;
196
197   len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0);
198   if (len > 0)
199     {
200       p = (char *)xmalloc (len + 2);
201       *p = '\0';
202       confstr (_CS_PATH, p, len);
203       return (p);
204     }
205   else
206     return (savestring (STANDARD_UTILS_PATH));
207 #else /* !_CS_PATH || !HAVE_CONFSTR  */
208 #  if defined (CS_PATH)
209   return (savestring (CS_PATH));
210 #  else
211   return (savestring (STANDARD_UTILS_PATH));
212 #  endif /* !CS_PATH */
213 #endif /* !_CS_PATH || !HAVE_CONFSTR */
214 }