Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 1, or (at your option) any later
+Software Foundation; either version 2, or (at your option) any later
version.
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
-Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
$PRODUCES command.c
$BUILTIN command
$FUNCTION command_builtin
-$SHORT_DOC command [-pVv] [command [arg ...]]
+$SHORT_DOC command [-pVv] command [arg ...]
Runs COMMAND with ARGS ignoring shell functions. If you have a shell
function called `ls', and you wish to call the command `ls', you can
say "command ls". If the -p option is given, a default value is used
The -V option produces a more verbose description.
$END
-#if defined (HAVE_STRING_H)
-# include <string.h>
-#else /* !HAVE_STRING_H */
-# include <strings.h>
-#endif /* !HAVE_STRING_H */
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+# ifdef _MINIX
+# include <sys/types.h>
+# endif
+# include <unistd.h>
+#endif
+
+#include "../bashansi.h"
#include "../shell.h"
+#include "../execute_cmd.h"
+#include "../flags.h"
#include "bashgetopt.h"
+#include "common.h"
+
+#if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR
+extern size_t confstr __P((int, char *, size_t));
+#endif
extern int subshell_environment;
-static void restore_path ();
-static char *get_standard_path ();
+static void restore_path __P((char *));
+static char *get_standard_path __P((void));
/* Run the commands mentioned in LIST without paying attention to shell
functions. */
command_builtin (list)
WORD_LIST *list;
{
- int result, verbose = 0, use_standard_path = 0, opt;
- char *old_path;
-
+ int result, verbose, use_standard_path, opt;
+ char *old_path, *standard_path;
+ COMMAND *command;
+
+ verbose = use_standard_path = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "pvV")) != -1)
{
case 'v':
verbose = 4;
break;
-
default:
- report_bad_option ();
- builtin_error ("usage: command [-pvV] [command [arg...]]");
+ builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
- if (!list)
+ if (list == 0)
return (EXECUTION_SUCCESS);
if (verbose)
{
- int found, any_found = 0;
+ int found, any_found;
- while (list)
+ for (any_found = 0; list; list = list->next)
{
-
found = describe_command (list->word->word, verbose, 0);
- if (!found)
+ if (found == 0)
builtin_error ("%s: not found", list->word->word);
any_found += found;
- list = list->next;
}
return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
+#if defined (RESTRICTED_SHELL)
+ if (use_standard_path && restricted)
+ {
+ builtin_error ("restricted: cannot use -p");
+ return (EXECUTION_FAILURE);
+ }
+#endif
+
begin_unwind_frame ("command_builtin");
/* We don't want this to be reparsed (consider command echo 'foo &'), so
just make a simple_command structure and call execute_command with it. */
- {
- COMMAND *command;
-
- if (use_standard_path)
- {
- char *standard_path;
-
- old_path = get_string_value ("PATH");
- if (old_path)
- old_path = savestring (old_path);
- else
- old_path = savestring ("");
- add_unwind_protect ((Function *)restore_path, old_path);
-
- standard_path = get_standard_path ();
- bind_variable ("PATH", standard_path);
- free (standard_path);
- }
- command = make_bare_simple_command ();
- command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
- command->value.Simple->redirects = (REDIRECT *)NULL;
- command->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
- command->value.Simple->flags |= (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION);
- /* If we're in a subshell, see if we can get away without forking
- again, since we've already forked to run this builtin. */
- if (subshell_environment)
- {
- command->flags |= CMD_NO_FORK;
- command->value.Simple->flags |= CMD_NO_FORK;
- }
- add_unwind_protect ((char *)dispose_command, command);
- result = execute_command (command);
- }
+ if (use_standard_path)
+ {
+ old_path = get_string_value ("PATH");
+ /* If old_path is NULL, $PATH is unset. If so, we want to make sure
+ it's unset after this command completes. */
+ if (old_path)
+ old_path = savestring (old_path);
+ add_unwind_protect ((Function *)restore_path, old_path);
+
+ standard_path = get_standard_path ();
+ bind_variable ("PATH", standard_path ? standard_path : "");
+ FREE (standard_path);
+ }
+
+#define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN)
+
+ command = make_bare_simple_command ();
+ command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
+ command->value.Simple->redirects = (REDIRECT *)NULL;
+ command->flags |= COMMAND_BUILTIN_FLAGS;
+ command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS;
+#if 0
+ /* This breaks for things like ( cd /tmp ; command z ababa ; echo next )
+ or $(command echo a ; command echo b;) or even
+ { command echo a; command echo b; } & */
+ /* If we're in a subshell, see if we can get away without forking
+ again, since we've already forked to run this builtin. */
+ if (subshell_environment)
+ {
+ command->flags |= CMD_NO_FORK;
+ command->value.Simple->flags |= CMD_NO_FORK;
+ }
+#endif
+ add_unwind_protect ((char *)dispose_command, command);
+ result = execute_command (command);
run_unwind_frame ("command_builtin");
restore_path (var)
char *var;
{
- bind_variable ("PATH", var);
- free (var);
+ if (var)
+ {
+ bind_variable ("PATH", var);
+ free (var);
+ }
+ else
+ unbind_variable ("PATH");
}
/* Return a value for PATH that is guaranteed to find all of the standard
static char *
get_standard_path ()
{
-#if defined (_CS_PATH) && !defined (hpux_7) && !defined (NetBSD)
+#if defined (_CS_PATH) && defined (HAVE_CONFSTR)
char *p;
size_t len;
len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0);
- p = xmalloc ((int)len + 2);
- *p = '\0';
- confstr (_CS_PATH, p, len);
- return (p);
-#else /* !_CSPATH || hpux_7 || NetBSD */
+ if (len > 0)
+ {
+ p = (char *)xmalloc (len + 2);
+ *p = '\0';
+ confstr (_CS_PATH, p, len);
+ return (p);
+ }
+ else
+ return (savestring (STANDARD_UTILS_PATH));
+#else /* !_CS_PATH || !HAVE_CONFSTR */
# if defined (CS_PATH)
return (savestring (CS_PATH));
# else
return (savestring (STANDARD_UTILS_PATH));
# endif /* !CS_PATH */
-#endif /* !_CS_PATH || hpux_7 */
+#endif /* !_CS_PATH || !HAVE_CONFSTR */
}