]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/exec.def
Imported from ../bash-2.04.tar.gz.
[thirdparty/bash.git] / builtins / exec.def
CommitLineData
726f6388
JA
1This file is exec.def, from which is created exec.c.
2It implements the builtin "exec" in Bash.
3
4Copyright (C) 1987, 1989, 1991 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 it under
9the terms of the GNU General Public License as published by the Free
bb70624e 10Software Foundation; either version 2, or (at your option) any later
726f6388
JA
11version.
12
13Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with Bash; see the file COPYING. If not, write to the Free Software
bb70624e 20Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
726f6388
JA
21
22$PRODUCES exec.c
23
24$BUILTIN exec
25$FUNCTION exec_builtin
ccc6cda3 26$SHORT_DOC exec [-cl] [-a name] file [redirection ...]
726f6388
JA
27Exec FILE, replacing this shell with the specified program.
28If FILE is not specified, the redirections take effect in this
ccc6cda3
JA
29shell. If the first argument is `-l', then place a dash in the
30zeroth arg passed to FILE, as login does. If the `-c' option
31is supplied, FILE is executed with a null environment. The `-a'
32option means to make set argv[0] of the executed process to NAME.
33If the file cannot be executed and the shell is not interactive,
34then the shell exits, unless the shell option `execfail' is set.
726f6388
JA
35$END
36
ccc6cda3
JA
37#include <config.h>
38
d166f048 39#include "../bashtypes.h"
bb70624e 40#include "posixstat.h"
726f6388
JA
41#include <signal.h>
42#include <errno.h>
43
ccc6cda3
JA
44#if defined (HAVE_UNISTD_H)
45# include <unistd.h>
46#endif
47
48#include "../bashansi.h"
49
50#include "../shell.h"
726f6388 51#include "../execute_cmd.h"
cce855bc 52#include "../findcmd.h"
ccc6cda3
JA
53#if defined (JOB_CONTROL)
54# include "../jobs.h"
55#endif
726f6388 56#include "../flags.h"
ccc6cda3
JA
57#include "../trap.h"
58#if defined (HISTORY)
59# include "../bashhist.h"
60#endif
61#include "common.h"
62#include "bashgetopt.h"
726f6388
JA
63
64/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
65#if !defined (errno)
66extern int errno;
67#endif /* !errno */
ccc6cda3 68
d166f048 69extern int interactive, interactive_shell, subshell_environment;
726f6388
JA
70extern REDIRECT *redirection_undo_list;
71
ccc6cda3
JA
72int no_exit_on_failed_exec;
73
74/* If the user wants this to look like a login shell, then
75 prepend a `-' onto NAME and return the new name. */
76static char *
77mkdashname (name)
78 char *name;
79{
80 char *ret;
81
82 ret = xmalloc (2 + strlen (name));
83 ret[0] = '-';
84 strcpy (ret + 1, name);
85 return ret;
86}
87
726f6388
JA
88int
89exec_builtin (list)
90 WORD_LIST *list;
91{
92 int exit_value = EXECUTION_FAILURE;
ccc6cda3 93 int cleanenv, login, opt;
d166f048 94 char *argv0, *command, **args, **env, *newname, *com2;
726f6388 95
ccc6cda3
JA
96 cleanenv = login = 0;
97 argv0 = (char *)NULL;
98
99 reset_internal_getopt ();
100 while ((opt = internal_getopt (list, "cla:")) != -1)
101 {
102 switch (opt)
103 {
104 case 'c':
105 cleanenv = 1;
106 break;
107 case 'l':
108 login = 1;
109 break;
110 case 'a':
111 argv0 = list_optarg;
112 break;
113 default:
114 builtin_usage ();
115 return (EX_USAGE);
116 }
117 }
118 list = loptend;
726f6388
JA
119
120 /* First, let the redirections remain. */
121 dispose_redirects (redirection_undo_list);
122 redirection_undo_list = (REDIRECT *)NULL;
123
ccc6cda3 124 if (list == 0)
726f6388 125 return (EXECUTION_SUCCESS);
ccc6cda3
JA
126
127#if defined (RESTRICTED_SHELL)
128 if (restricted)
726f6388 129 {
ccc6cda3
JA
130 builtin_error ("restricted");
131 return (EXECUTION_FAILURE);
132 }
133#endif /* RESTRICTED_SHELL */
726f6388 134
ccc6cda3 135 args = word_list_to_argv (list, 1, 0, (int *)NULL);
726f6388 136
ccc6cda3
JA
137 /* A command with a slash anywhere in its name is not looked up in $PATH. */
138 command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
726f6388 139
ccc6cda3
JA
140 if (command == 0)
141 {
142 builtin_error ("%s: not found", args[0]);
143 exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
144 goto failed_exec;
145 }
726f6388 146
d166f048
JA
147 com2 = full_pathname (command);
148 if (com2)
149 {
150 if (command != args[0])
151 free (command);
152 command = com2;
153 }
726f6388 154
ccc6cda3
JA
155 if (argv0)
156 {
157 free (args[0]);
158 args[0] = login ? mkdashname (argv0) : savestring (argv0);
159 }
160 else if (login)
161 {
162 newname = mkdashname (args[0]);
163 free (args[0]);
164 args[0] = newname;
165 }
726f6388 166
ccc6cda3
JA
167 /* Decrement SHLVL by 1 so a new shell started here has the same value,
168 preserving the appearance. After we do that, we need to change the
169 exported environment to include the new value. */
170 if (cleanenv == 0)
171 adjust_shell_level (-1);
726f6388 172
ccc6cda3
JA
173 if (cleanenv)
174 env = (char **)NULL;
175 else
176 {
726f6388 177 maybe_make_export_env ();
ccc6cda3
JA
178 env = export_env;
179 }
726f6388
JA
180
181#if defined (HISTORY)
d166f048
JA
182 if (interactive_shell && subshell_environment == 0)
183 maybe_save_shell_history ();
726f6388 184#endif /* HISTORY */
ccc6cda3
JA
185
186 restore_original_signals ();
726f6388
JA
187
188#if defined (JOB_CONTROL)
ccc6cda3
JA
189 if (subshell_environment == 0)
190 end_job_control ();
726f6388
JA
191#endif /* JOB_CONTROL */
192
ccc6cda3 193 shell_execve (command, args, env);
bc4cd23c
JA
194
195 /* We have to set this to NULL because shell_execve has called realloc()
196 to stuff more items at the front of the array, which may have caused
197 the memory to be freed by realloc(). We don't want to free it twice. */
198 args = (char **)NULL;
ccc6cda3
JA
199 if (cleanenv == 0)
200 adjust_shell_level (1);
726f6388 201
ccc6cda3
JA
202 if (executable_file (command) == 0)
203 {
204 builtin_error ("%s: cannot execute: %s", command, strerror (errno));
205 exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
206 }
207 else
208 file_error (command);
726f6388 209
ccc6cda3
JA
210failed_exec:
211 if (command)
212 free (command);
726f6388 213
ccc6cda3
JA
214 if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
215 exit_shell (exit_value);
726f6388 216
d166f048
JA
217 if (args)
218 free_array (args);
219
ccc6cda3
JA
220 initialize_traps ();
221 reinitialize_signals ();
726f6388
JA
222
223#if defined (JOB_CONTROL)
ccc6cda3 224 restart_job_control ();
726f6388
JA
225#endif /* JOB_CONTROL */
226
ccc6cda3 227 return (exit_value);
726f6388 228}