Imported from ../bash-2.05b.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-2002 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 #if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR
53 extern size_t confstr __P((int, char *, size_t));
54 #endif
55
56 extern int subshell_environment;
57
58 static void restore_path __P((char *));
59 static char *get_standard_path __P((void));
60
61 /* Run the commands mentioned in LIST without paying attention to shell
62    functions. */
63 int
64 command_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;    /* 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)
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 : "");
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'. */
167 static void
168 restore_path (var)
169      char *var;
170 {
171   if (var)
172     {
173       bind_variable ("PATH", var);
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. */
183 static char *
184 get_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 }