1This file is command.def, from which is created command.c.
2It implements the builtin "command" in Bash.
3
4Copyright (C) 1987-2020 Free Software Foundation, Inc.
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
8Bash is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
12
13Bash is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along 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 ...]
26Execute a simple command or display information about commands.
27
28Runs COMMAND with ARGS suppressing  shell function lookup, or display
29information about the specified COMMANDs.  Can be used to invoke commands
30on disk when a function with the same name exists.
31
32Options:
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
38Exit Status:
39Returns 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
60extern size_t confstr PARAMS((int, char *, size_t));
61#endif
62
63/* Run the commands mentioned in LIST without paying attention to shell
64   functions. */
65int
66command_builtin (list)
67     WORD_LIST *list;
68{
69  int result, verbose, use_standard_path, opt;
70  COMMAND *command;
71
72  verbose = use_standard_path = 0;
73  reset_internal_getopt ();
74  while ((opt = internal_getopt (list, "pvV")) != -1)
75    {
76      switch (opt)
77	{
78	case 'p':
79	  use_standard_path = CDESC_STDPATH;
80	  break;
81	case 'V':
82	  verbose = CDESC_SHORTDESC|CDESC_ABSPATH;	/* look in common.h for constants */
83	  break;
84	case 'v':
85	  verbose = CDESC_REUSABLE;	/* ditto */
86	  break;
87	CASE_HELPOPT;
88	default:
89	  builtin_usage ();
90	  return (EX_USAGE);
91	}
92    }
93  list = loptend;
94
95  if (list == 0)
96    return (EXECUTION_SUCCESS);
97
98#if defined (RESTRICTED_SHELL)
99  if (use_standard_path && restricted)
100    {
101      sh_restricted ("-p");
102      return (EXECUTION_FAILURE);
103    }
104#endif
105
106  if (verbose)
107    {
108      int found, any_found;
109
110      for (any_found = 0; list; list = list->next)
111	{
112	  found = describe_command (list->word->word, verbose|use_standard_path);
113
114	  if (found == 0 && verbose != CDESC_REUSABLE)
115	    sh_notfound (list->word->word);
116
117	  any_found += found;
118	}
119
120      return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
121    }
122
123  begin_unwind_frame ("command_builtin");
124
125#define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN | (use_standard_path ? CMD_STDPATH : 0))
126
127#ifdef DEBUG
128  itrace("command_builtin: running execute_command for `%s'", list->word->word);
129#endif
130
131  /* We don't want this to be reparsed (consider command echo 'foo &'), so
132     just make a simple_command structure and call execute_command with it. */
133  command = make_bare_simple_command ();
134  command->value.Simple->words = (WORD_LIST *)copy_word_list (list);
135  command->value.Simple->redirects = (REDIRECT *)NULL;
136  command->flags |= COMMAND_BUILTIN_FLAGS;
137  command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS;
138
139  add_unwind_protect ((char *)dispose_command, command);
140  result = execute_command (command);
141
142  run_unwind_frame ("command_builtin");
143
144  return (result);
145}
146