blob: 0837a9834b1160d0b104f6ff3ce62f33b1e2db46 [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
Jari Aalto31859422009-01-12 13:36:28 +00004Copyright (C) 1987-2009 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
Jari Aalto31859422009-01-12 13:36:28 +000025$SHORT_DOC exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
26Replace 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
34 -c execute COMMAND with an empty environment
35 -l place a dash in the zeroth argument to COMMAND
36
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
55#include "../bashansi.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000056#include "../bashintl.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000057
58#include "../shell.h"
Jari Aalto726f6381996-08-26 18:22:31 +000059#include "../execute_cmd.h"
Jari Aaltocce855b1998-04-17 19:52:44 +000060#include "../findcmd.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000061#if defined (JOB_CONTROL)
62# include "../jobs.h"
63#endif
Jari Aalto726f6381996-08-26 18:22:31 +000064#include "../flags.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000065#include "../trap.h"
66#if defined (HISTORY)
67# include "../bashhist.h"
68#endif
69#include "common.h"
70#include "bashgetopt.h"
Jari Aalto726f6381996-08-26 18:22:31 +000071
72/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
73#if !defined (errno)
74extern int errno;
75#endif /* !errno */
Jari Aaltoccc6cda1996-12-23 17:02:34 +000076
Jari Aaltof73dda02001-11-13 17:56:06 +000077extern int subshell_environment;
Jari Aalto726f6381996-08-26 18:22:31 +000078extern REDIRECT *redirection_undo_list;
79
Jari Aaltoccc6cda1996-12-23 17:02:34 +000080int no_exit_on_failed_exec;
81
82/* If the user wants this to look like a login shell, then
83 prepend a `-' onto NAME and return the new name. */
84static char *
85mkdashname (name)
86 char *name;
87{
88 char *ret;
89
Jari Aaltof73dda02001-11-13 17:56:06 +000090 ret = (char *)xmalloc (2 + strlen (name));
Jari Aaltoccc6cda1996-12-23 17:02:34 +000091 ret[0] = '-';
92 strcpy (ret + 1, name);
93 return ret;
94}
95
Jari Aalto726f6381996-08-26 18:22:31 +000096int
97exec_builtin (list)
98 WORD_LIST *list;
99{
100 int exit_value = EXECUTION_FAILURE;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000101 int cleanenv, login, opt;
Jari Aaltod166f041997-06-05 14:59:13 +0000102 char *argv0, *command, **args, **env, *newname, *com2;
Jari Aalto726f6381996-08-26 18:22:31 +0000103
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000104 cleanenv = login = 0;
105 argv0 = (char *)NULL;
106
107 reset_internal_getopt ();
108 while ((opt = internal_getopt (list, "cla:")) != -1)
109 {
110 switch (opt)
111 {
112 case 'c':
113 cleanenv = 1;
114 break;
115 case 'l':
116 login = 1;
117 break;
118 case 'a':
119 argv0 = list_optarg;
120 break;
121 default:
122 builtin_usage ();
123 return (EX_USAGE);
124 }
125 }
126 list = loptend;
Jari Aalto726f6381996-08-26 18:22:31 +0000127
128 /* First, let the redirections remain. */
129 dispose_redirects (redirection_undo_list);
130 redirection_undo_list = (REDIRECT *)NULL;
131
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000132 if (list == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000133 return (EXECUTION_SUCCESS);
Jari Aalto726f6381996-08-26 18:22:31 +0000134
135#if defined (RESTRICTED_SHELL)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000136 if (restricted)
137 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000138 sh_restricted ((char *)NULL);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000139 return (EXECUTION_FAILURE);
140 }
Jari Aalto726f6381996-08-26 18:22:31 +0000141#endif /* RESTRICTED_SHELL */
142
Jari Aalto7117c2d2002-07-17 14:10:11 +0000143 args = strvec_from_word_list (list, 1, 0, (int *)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +0000144
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000145 /* A command with a slash anywhere in its name is not looked up in $PATH. */
146 command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
Jari Aalto726f6381996-08-26 18:22:31 +0000147
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000148 if (command == 0)
149 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000150 sh_notfound (args[0]);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000151 exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
152 goto failed_exec;
153 }
Jari Aalto726f6381996-08-26 18:22:31 +0000154
Jari Aaltod166f041997-06-05 14:59:13 +0000155 com2 = full_pathname (command);
156 if (com2)
157 {
158 if (command != args[0])
159 free (command);
160 command = com2;
161 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000162
163 if (argv0)
164 {
165 free (args[0]);
166 args[0] = login ? mkdashname (argv0) : savestring (argv0);
167 }
168 else if (login)
169 {
170 newname = mkdashname (args[0]);
171 free (args[0]);
172 args[0] = newname;
173 }
174
175 /* Decrement SHLVL by 1 so a new shell started here has the same value,
176 preserving the appearance. After we do that, we need to change the
177 exported environment to include the new value. */
178 if (cleanenv == 0)
179 adjust_shell_level (-1);
180
181 if (cleanenv)
182 env = (char **)NULL;
183 else
184 {
Jari Aalto726f6381996-08-26 18:22:31 +0000185 maybe_make_export_env ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000186 env = export_env;
187 }
Jari Aalto726f6381996-08-26 18:22:31 +0000188
189#if defined (HISTORY)
Jari Aaltod166f041997-06-05 14:59:13 +0000190 if (interactive_shell && subshell_environment == 0)
191 maybe_save_shell_history ();
Jari Aalto726f6381996-08-26 18:22:31 +0000192#endif /* HISTORY */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000193
194 restore_original_signals ();
Jari Aalto726f6381996-08-26 18:22:31 +0000195
196#if defined (JOB_CONTROL)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000197 if (subshell_environment == 0)
198 end_job_control ();
Jari Aalto726f6381996-08-26 18:22:31 +0000199#endif /* JOB_CONTROL */
200
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000201 shell_execve (command, args, env);
Jari Aaltobc4cd231998-07-23 14:37:54 +0000202
203 /* We have to set this to NULL because shell_execve has called realloc()
204 to stuff more items at the front of the array, which may have caused
205 the memory to be freed by realloc(). We don't want to free it twice. */
206 args = (char **)NULL;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000207 if (cleanenv == 0)
208 adjust_shell_level (1);
Jari Aalto726f6381996-08-26 18:22:31 +0000209
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000210 if (executable_file (command) == 0)
211 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000212 builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000213 exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
Jari Aalto726f6381996-08-26 18:22:31 +0000214 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000215 else
216 file_error (command);
217
218failed_exec:
Jari Aaltob80f6442004-07-27 13:29:18 +0000219 FREE (command);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000220
221 if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
222 exit_shell (exit_value);
223
Jari Aaltod166f041997-06-05 14:59:13 +0000224 if (args)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000225 strvec_dispose (args);
Jari Aaltod166f041997-06-05 14:59:13 +0000226
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000227 initialize_traps ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000228 initialize_signals (1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000229
230#if defined (JOB_CONTROL)
Jari Aalto95732b42005-12-07 14:08:12 +0000231 if (interactive_shell || job_control)
232 restart_job_control ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000233#endif /* JOB_CONTROL */
234
235 return (exit_value);
Jari Aalto726f6381996-08-26 18:22:31 +0000236}