blob: cbcb641a68ad2cc847f4244885ceb1cc06ef327e [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001This file is exec.def, from which is created exec.c.
2It implements the builtin "exec" in Bash.
3
Chet Ramey8868eda2020-12-06 15:51:17 -05004Copyright (C) 1987-2019 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00005
6This file is part of GNU Bash, the Bourne Again SHell.
7
Jari Aalto31859422009-01-12 13:36:28 +00008Bash 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.
Jari Aalto726f6381996-08-26 18:22:31 +000012
Jari Aalto31859422009-01-12 13:36:28 +000013Bash 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.
Jari Aalto726f6381996-08-26 18:22:31 +000017
Jari Aalto31859422009-01-12 13:36:28 +000018You should have received a copy of the GNU General Public License
19along with Bash. If not, see <http://www.gnu.org/licenses/>.
Jari Aalto726f6381996-08-26 18:22:31 +000020
21$PRODUCES exec.c
22
23$BUILTIN exec
24$FUNCTION exec_builtin
Chet Ramey8868eda2020-12-06 15:51:17 -050025$SHORT_DOC exec [-cl] [-a name] [command [argument ...]] [redirection ...]
Jari Aalto31859422009-01-12 13:36:28 +000026Replace the shell with the given command.
27
28Execute COMMAND, replacing this shell with the specified program.
29ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified,
30any redirections take effect in the current shell.
31
32Options:
33 -a name pass NAME as the zeroth argument to COMMAND
Chet Rameya0c0a002016-09-15 16:59:08 -040034 -c execute COMMAND with an empty environment
35 -l place a dash in the zeroth argument to COMMAND
Jari Aalto31859422009-01-12 13:36:28 +000036
37If the command cannot be executed, a non-interactive shell exits, unless
38the shell option `execfail' is set.
39
40Exit Status:
41Returns success unless COMMAND is not found or a redirection error occurs.
Jari Aalto726f6381996-08-26 18:22:31 +000042$END
43
Jari Aaltoccc6cda1996-12-23 17:02:34 +000044#include <config.h>
45
Jari Aaltod166f041997-06-05 14:59:13 +000046#include "../bashtypes.h"
Jari Aaltobb706242000-03-17 21:46:59 +000047#include "posixstat.h"
Jari Aalto726f6381996-08-26 18:22:31 +000048#include <signal.h>
49#include <errno.h>
50
Jari Aaltoccc6cda1996-12-23 17:02:34 +000051#if defined (HAVE_UNISTD_H)
52# include <unistd.h>
53#endif
54
Chet Ramey8868eda2020-12-06 15:51:17 -050055#include <stdio.h>
56
Jari Aaltoccc6cda1996-12-23 17:02:34 +000057#include "../bashansi.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000058#include "../bashintl.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000059
60#include "../shell.h"
Jari Aalto726f6381996-08-26 18:22:31 +000061#include "../execute_cmd.h"
Jari Aaltocce855b1998-04-17 19:52:44 +000062#include "../findcmd.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000063#if defined (JOB_CONTROL)
64# include "../jobs.h"
65#endif
Jari Aalto726f6381996-08-26 18:22:31 +000066#include "../flags.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000067#include "../trap.h"
68#if defined (HISTORY)
69# include "../bashhist.h"
70#endif
71#include "common.h"
72#include "bashgetopt.h"
Chet Rameyd233b482019-01-07 09:27:52 -050073#include "input.h"
Jari Aalto726f6381996-08-26 18:22:31 +000074
75/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
76#if !defined (errno)
77extern int errno;
78#endif /* !errno */
Jari Aaltoccc6cda1996-12-23 17:02:34 +000079
Jari Aalto726f6381996-08-26 18:22:31 +000080extern REDIRECT *redirection_undo_list;
Chet Ramey495aee42011-11-22 19:11:26 -050081extern char *exec_argv0;
Jari Aalto726f6381996-08-26 18:22:31 +000082
Jari Aaltoccc6cda1996-12-23 17:02:34 +000083int no_exit_on_failed_exec;
84
85/* If the user wants this to look like a login shell, then
86 prepend a `-' onto NAME and return the new name. */
87static char *
88mkdashname (name)
89 char *name;
90{
91 char *ret;
92
Jari Aaltof73dda02001-11-13 17:56:06 +000093 ret = (char *)xmalloc (2 + strlen (name));
Jari Aaltoccc6cda1996-12-23 17:02:34 +000094 ret[0] = '-';
95 strcpy (ret + 1, name);
96 return ret;
97}
98
Jari Aalto726f6381996-08-26 18:22:31 +000099int
100exec_builtin (list)
101 WORD_LIST *list;
102{
103 int exit_value = EXECUTION_FAILURE;
Chet Ramey8868eda2020-12-06 15:51:17 -0500104 int cleanenv, login, opt, orig_job_control;
Jari Aaltod166f041997-06-05 14:59:13 +0000105 char *argv0, *command, **args, **env, *newname, *com2;
Jari Aalto726f6381996-08-26 18:22:31 +0000106
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000107 cleanenv = login = 0;
Chet Ramey495aee42011-11-22 19:11:26 -0500108 exec_argv0 = argv0 = (char *)NULL;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000109
110 reset_internal_getopt ();
111 while ((opt = internal_getopt (list, "cla:")) != -1)
112 {
113 switch (opt)
114 {
115 case 'c':
116 cleanenv = 1;
117 break;
118 case 'l':
119 login = 1;
120 break;
121 case 'a':
122 argv0 = list_optarg;
123 break;
Chet Rameya0c0a002016-09-15 16:59:08 -0400124 CASE_HELPOPT;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000125 default:
126 builtin_usage ();
127 return (EX_USAGE);
128 }
129 }
130 list = loptend;
Jari Aalto726f6381996-08-26 18:22:31 +0000131
132 /* First, let the redirections remain. */
133 dispose_redirects (redirection_undo_list);
134 redirection_undo_list = (REDIRECT *)NULL;
135
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000136 if (list == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000137 return (EXECUTION_SUCCESS);
Jari Aalto726f6381996-08-26 18:22:31 +0000138
139#if defined (RESTRICTED_SHELL)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000140 if (restricted)
141 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000142 sh_restricted ((char *)NULL);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000143 return (EXECUTION_FAILURE);
144 }
Jari Aalto726f6381996-08-26 18:22:31 +0000145#endif /* RESTRICTED_SHELL */
146
Jari Aalto7117c2d2002-07-17 14:10:11 +0000147 args = strvec_from_word_list (list, 1, 0, (int *)NULL);
Chet Rameya0c0a002016-09-15 16:59:08 -0400148 env = (char **)0;
Jari Aalto726f6381996-08-26 18:22:31 +0000149
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000150 /* A command with a slash anywhere in its name is not looked up in $PATH. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500151 command = absolute_program (args[0]) ? args[0] : search_for_command (args[0], 1);
Jari Aalto726f6381996-08-26 18:22:31 +0000152
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000153 if (command == 0)
154 {
Chet Ramey495aee42011-11-22 19:11:26 -0500155 if (file_isdir (args[0]))
156 {
157#if defined (EISDIR)
158 builtin_error (_("%s: cannot execute: %s"), args[0], strerror (EISDIR));
159#else
160 builtin_error (_("%s: cannot execute: %s"), args[0], strerror (errno));
161#endif
162 exit_value = EX_NOEXEC;
163 }
164 else
165 {
166 sh_notfound (args[0]);
167 exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
168 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000169 goto failed_exec;
170 }
Jari Aalto726f6381996-08-26 18:22:31 +0000171
Jari Aaltod166f041997-06-05 14:59:13 +0000172 com2 = full_pathname (command);
173 if (com2)
174 {
175 if (command != args[0])
176 free (command);
177 command = com2;
178 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000179
180 if (argv0)
181 {
182 free (args[0]);
183 args[0] = login ? mkdashname (argv0) : savestring (argv0);
Chet Ramey495aee42011-11-22 19:11:26 -0500184 exec_argv0 = savestring (args[0]);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000185 }
186 else if (login)
187 {
188 newname = mkdashname (args[0]);
189 free (args[0]);
190 args[0] = newname;
191 }
192
193 /* Decrement SHLVL by 1 so a new shell started here has the same value,
194 preserving the appearance. After we do that, we need to change the
Chet Rameyd233b482019-01-07 09:27:52 -0500195 exported environment to include the new value. If we've already forked
196 and are in a subshell, we don't want to decrement the shell level,
197 since we are `increasing' the level */
198
199 if (cleanenv == 0 && (subshell_environment & SUBSHELL_PAREN) == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000200 adjust_shell_level (-1);
201
202 if (cleanenv)
Chet Rameya0c0a002016-09-15 16:59:08 -0400203 {
204 env = strvec_create (1);
205 env[0] = (char *)0;
206 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000207 else
208 {
Jari Aalto726f6381996-08-26 18:22:31 +0000209 maybe_make_export_env ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000210 env = export_env;
211 }
Jari Aalto726f6381996-08-26 18:22:31 +0000212
213#if defined (HISTORY)
Jari Aaltod166f041997-06-05 14:59:13 +0000214 if (interactive_shell && subshell_environment == 0)
215 maybe_save_shell_history ();
Jari Aalto726f6381996-08-26 18:22:31 +0000216#endif /* HISTORY */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000217
218 restore_original_signals ();
Jari Aalto726f6381996-08-26 18:22:31 +0000219
220#if defined (JOB_CONTROL)
Chet Ramey8868eda2020-12-06 15:51:17 -0500221 orig_job_control = job_control; /* XXX - was also interactive_shell */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000222 if (subshell_environment == 0)
223 end_job_control ();
Chet Rameya0c0a002016-09-15 16:59:08 -0400224 if (interactive || job_control)
225 default_tty_job_signals (); /* undo initialize_job_signals */
Jari Aalto726f6381996-08-26 18:22:31 +0000226#endif /* JOB_CONTROL */
227
Chet Rameyd233b482019-01-07 09:27:52 -0500228#if defined (BUFFERED_INPUT)
229 if (default_buffered_input >= 0)
230 sync_buffered_stream (default_buffered_input);
231#endif
232
Chet Ramey495aee42011-11-22 19:11:26 -0500233 exit_value = shell_execve (command, args, env);
Jari Aaltobc4cd231998-07-23 14:37:54 +0000234
235 /* We have to set this to NULL because shell_execve has called realloc()
236 to stuff more items at the front of the array, which may have caused
237 the memory to be freed by realloc(). We don't want to free it twice. */
238 args = (char **)NULL;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000239 if (cleanenv == 0)
240 adjust_shell_level (1);
Jari Aalto726f6381996-08-26 18:22:31 +0000241
Chet Ramey495aee42011-11-22 19:11:26 -0500242 if (exit_value == EX_NOTFOUND) /* no duplicate error message */
243 goto failed_exec;
244 else if (executable_file (command) == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000245 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000246 builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000247 exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
Jari Aalto726f6381996-08-26 18:22:31 +0000248 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000249 else
250 file_error (command);
251
252failed_exec:
Jari Aaltob80f6442004-07-27 13:29:18 +0000253 FREE (command);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000254
255 if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
256 exit_shell (exit_value);
257
Jari Aaltod166f041997-06-05 14:59:13 +0000258 if (args)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000259 strvec_dispose (args);
Jari Aaltod166f041997-06-05 14:59:13 +0000260
Chet Rameya0c0a002016-09-15 16:59:08 -0400261 if (env && env != export_env)
262 strvec_dispose (env);
263
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000264 initialize_traps ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000265 initialize_signals (1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000266
267#if defined (JOB_CONTROL)
Chet Ramey8868eda2020-12-06 15:51:17 -0500268 if (orig_job_control)
Jari Aalto95732b42005-12-07 14:08:12 +0000269 restart_job_control ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000270#endif /* JOB_CONTROL */
271
272 return (exit_value);
Jari Aalto726f6381996-08-26 18:22:31 +0000273}