b84613e79e41ae5798d27c65558cf55146334e24
[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 #if defined (HAVE_STRING_H)
36 #  include <string.h>
37 #else /* !HAVE_STRING_H */
38 #  include <strings.h>
39 #endif /* !HAVE_STRING_H */
40
41 #include "../shell.h"
42 #include "bashgetopt.h"
43
44 extern int subshell_environment;
45
46 static void restore_path ();
47 static char *get_standard_path ();
48
49 /* Run the commands mentioned in LIST without paying attention to shell
50    functions. */
51 int
52 command_builtin (list)
53      WORD_LIST *list;
54 {
55   int result, verbose = 0, use_standard_path = 0, opt;
56   char *old_path;
57   
58   reset_internal_getopt ();
59   while ((opt = internal_getopt (list, "pvV")) != -1)
60     {
61       switch (opt)
62         {
63         case 'p':
64           use_standard_path = 1;
65           break;
66         case 'V':
67           verbose = 2;
68           break;
69         case 'v':
70           verbose = 4;
71           break;
72
73         default:
74           report_bad_option ();
75           builtin_error ("usage: command [-pvV] [command [arg...]]");
76           return (EX_USAGE);
77         }
78     }
79   list = loptend;
80
81   if (!list)
82     return (EXECUTION_SUCCESS);
83
84   if (verbose)
85     {
86       int found, any_found = 0;
87
88       while (list)
89         {
90
91           found = describe_command (list->word->word, verbose, 0);
92
93           if (!found)
94             builtin_error ("%s: not found", list->word->word);
95
96           any_found += found;
97           list = list->next;
98         }
99       return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
100     }
101
102   begin_unwind_frame ("command_builtin");
103
104   /* We don't want this to be reparsed (consider command echo 'foo &'), so
105      just make a simple_command structure and call execute_command with it. */
106   {
107     COMMAND *command;
108
109     if (use_standard_path)
110       {
111         char *standard_path;
112
113         old_path = get_string_value ("PATH");
114         if (old_path)
115           old_path = savestring (old_path);
116         else
117           old_path = savestring ("");
118         add_unwind_protect ((Function *)restore_path, old_path);
119
120         standard_path = get_standard_path ();
121         bind_variable ("PATH", standard_path);
122         free (standard_path);
123       }
124     command = make_bare_simple_command ();
125     command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
126     command->value.Simple->redirects = (REDIRECT *)NULL;
127     command->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
128     command->value.Simple->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
129     /* If we're in a subshell, see if we can get away without forking
130        again, since we've already forked to run this builtin. */
131     if (subshell_environment)
132       {
133         command->flags |= CMD_NO_FORK;
134         command->value.Simple->flags |= CMD_NO_FORK;
135       }
136     add_unwind_protect ((char *)dispose_command, command);
137     result = execute_command (command);
138   }
139
140   run_unwind_frame ("command_builtin");
141
142   return (result);
143 }
144
145 /* Restore the value of the $PATH variable after replacing it when
146    executing `command -p'. */
147 static void
148 restore_path (var)
149      char *var;
150 {
151   bind_variable ("PATH", var);
152   free (var);
153 }
154
155 /* Return a value for PATH that is guaranteed to find all of the standard
156    utilities.  This uses Posix.2 configuration variables, if present.  It
157    uses a value defined in config.h as a last resort. */
158 static char *
159 get_standard_path ()
160 {
161 #if defined (_CS_PATH) && !defined (hpux_7) && !defined (NetBSD)
162   char *p;
163   size_t len;
164
165   len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0);
166   p = xmalloc ((int)len + 2);
167   *p = '\0';
168   confstr (_CS_PATH, p, len);
169   return (p);
170 #else /* !_CSPATH || hpux_7 || NetBSD */
171 #  if defined (CS_PATH)
172   return (savestring (CS_PATH));
173 #  else
174   return (savestring (STANDARD_UTILS_PATH));
175 #  endif /* !CS_PATH */
176 #endif /* !_CS_PATH || hpux_7 */
177 }