3a14dc6451f2c2b04d5873d6c1acc2ca19a02331
[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, 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, 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 #  include <unistd.h>
39 #endif
40
41 #include "../bashansi.h"
42
43 #include "../shell.h"
44 #include "../execute_cmd.h"
45 #include "../flags.h"
46 #include "bashgetopt.h"
47 #include "common.h"
48
49 extern int subshell_environment;
50
51 static void restore_path ();
52 static char *get_standard_path ();
53
54 /* Run the commands mentioned in LIST without paying attention to shell
55    functions. */
56 int
57 command_builtin (list)
58      WORD_LIST *list;
59 {
60   int result, verbose, use_standard_path, opt;
61   char *old_path, *standard_path;
62   COMMAND *command;
63
64   verbose = use_standard_path = 0;
65   reset_internal_getopt ();
66   while ((opt = internal_getopt (list, "pvV")) != -1)
67     {
68       switch (opt)
69         {
70         case 'p':
71           use_standard_path = 1;
72           break;
73         case 'V':
74           verbose = 2;
75           break;
76         case 'v':
77           verbose = 4;
78           break;
79         default:
80           builtin_usage ();
81           return (EX_USAGE);
82         }
83     }
84   list = loptend;
85
86   if (list == 0)
87     return (EXECUTION_SUCCESS);
88
89   if (verbose)
90     {
91       int found, any_found;
92
93       for (any_found = 0; list; list = list->next)
94         {
95           found = describe_command (list->word->word, verbose, 0);
96
97           if (found == 0)
98             builtin_error ("%s: not found", list->word->word);
99
100           any_found += found;
101         }
102       return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
103     }
104
105 #if defined (RESTRICTED_SHELL)
106   if (use_standard_path && restricted)
107     {
108       builtin_error ("restricted: cannot use -p");
109       return (EXECUTION_FAILURE);
110     }
111 #endif
112
113   begin_unwind_frame ("command_builtin");
114
115   /* We don't want this to be reparsed (consider command echo 'foo &'), so
116      just make a simple_command structure and call execute_command with it. */
117   if (use_standard_path)
118     {      
119       old_path = get_string_value ("PATH");
120       if (old_path)
121         old_path = savestring (old_path);
122       else
123         {
124           old_path = xmalloc (1);
125           old_path[0] = '\0';
126         }
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   bind_variable ("PATH", var);
166   free (var);
167 }
168
169 /* Return a value for PATH that is guaranteed to find all of the standard
170    utilities.  This uses Posix.2 configuration variables, if present.  It
171    uses a value defined in config.h as a last resort. */
172 static char *
173 get_standard_path ()
174 {
175 #if defined (_CS_PATH) && defined (HAVE_CONFSTR)
176   char *p;
177   size_t len;
178
179   len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0);
180   p = xmalloc ((int)len + 2);
181   *p = '\0';
182   confstr (_CS_PATH, p, len);
183   return (p);
184 #else /* !_CSPATH || !HAVE_CONFSTR  */
185 #  if defined (CS_PATH)
186   return (savestring (CS_PATH));
187 #  else
188   return (savestring (STANDARD_UTILS_PATH));
189 #  endif /* !CS_PATH */
190 #endif /* !_CS_PATH || !HAVE_CONFSTR */
191 }