source: vendor/bash/3.1/builtins/exec.def

Last change on this file was 3228, checked in by bird, 18 years ago

bash 3.1

File size: 5.5 KB
Line 
1This file is exec.def, from which is created exec.c.
2It implements the builtin "exec" in Bash.
3
4Copyright (C) 1987-2003 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
10Software Foundation; either version 2, or (at your option) any later
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
20Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
21
22$PRODUCES exec.c
23
24$BUILTIN exec
25$FUNCTION exec_builtin
26$SHORT_DOC exec [-cl] [-a name] file [redirection ...]
27Exec FILE, replacing this shell with the specified program.
28If FILE is not specified, the redirections take effect in this
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.
35$END
36
37#include <config.h>
38
39#include "../bashtypes.h"
40#include "posixstat.h"
41#include <signal.h>
42#include <errno.h>
43
44#if defined (HAVE_UNISTD_H)
45# include <unistd.h>
46#endif
47
48#include "../bashansi.h"
49#include "../bashintl.h"
50
51#include "../shell.h"
52#include "../execute_cmd.h"
53#include "../findcmd.h"
54#if defined (JOB_CONTROL)
55# include "../jobs.h"
56#endif
57#include "../flags.h"
58#include "../trap.h"
59#if defined (HISTORY)
60# include "../bashhist.h"
61#endif
62#include "common.h"
63#include "bashgetopt.h"
64
65/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
66#if !defined (errno)
67extern int errno;
68#endif /* !errno */
69
70extern int subshell_environment;
71extern REDIRECT *redirection_undo_list;
72
73int no_exit_on_failed_exec;
74
75/* If the user wants this to look like a login shell, then
76 prepend a `-' onto NAME and return the new name. */
77static char *
78mkdashname (name)
79 char *name;
80{
81 char *ret;
82
83 ret = (char *)xmalloc (2 + strlen (name));
84 ret[0] = '-';
85 strcpy (ret + 1, name);
86 return ret;
87}
88
89int
90exec_builtin (list)
91 WORD_LIST *list;
92{
93 int exit_value = EXECUTION_FAILURE;
94 int cleanenv, login, opt;
95 char *argv0, *command, **args, **env, *newname, *com2;
96
97 cleanenv = login = 0;
98 argv0 = (char *)NULL;
99
100 reset_internal_getopt ();
101 while ((opt = internal_getopt (list, "cla:")) != -1)
102 {
103 switch (opt)
104 {
105 case 'c':
106 cleanenv = 1;
107 break;
108 case 'l':
109 login = 1;
110 break;
111 case 'a':
112 argv0 = list_optarg;
113 break;
114 default:
115 builtin_usage ();
116 return (EX_USAGE);
117 }
118 }
119 list = loptend;
120
121 /* First, let the redirections remain. */
122 dispose_redirects (redirection_undo_list);
123 redirection_undo_list = (REDIRECT *)NULL;
124
125 if (list == 0)
126 return (EXECUTION_SUCCESS);
127
128#if defined (RESTRICTED_SHELL)
129 if (restricted)
130 {
131 sh_restricted ((char *)NULL);
132 return (EXECUTION_FAILURE);
133 }
134#endif /* RESTRICTED_SHELL */
135
136 args = strvec_from_word_list (list, 1, 0, (int *)NULL);
137
138 /* A command with a slash anywhere in its name is not looked up in $PATH. */
139 command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
140
141 if (command == 0)
142 {
143 sh_notfound (args[0]);
144 exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
145 goto failed_exec;
146 }
147
148 com2 = full_pathname (command);
149 if (com2)
150 {
151 if (command != args[0])
152 free (command);
153 command = com2;
154 }
155
156 if (argv0)
157 {
158 free (args[0]);
159 args[0] = login ? mkdashname (argv0) : savestring (argv0);
160 }
161 else if (login)
162 {
163 newname = mkdashname (args[0]);
164 free (args[0]);
165 args[0] = newname;
166 }
167
168 /* Decrement SHLVL by 1 so a new shell started here has the same value,
169 preserving the appearance. After we do that, we need to change the
170 exported environment to include the new value. */
171 if (cleanenv == 0)
172 adjust_shell_level (-1);
173
174 if (cleanenv)
175 env = (char **)NULL;
176 else
177 {
178 maybe_make_export_env ();
179 env = export_env;
180 }
181
182#if defined (HISTORY)
183 if (interactive_shell && subshell_environment == 0)
184 maybe_save_shell_history ();
185#endif /* HISTORY */
186
187 restore_original_signals ();
188
189#if defined (JOB_CONTROL)
190 if (subshell_environment == 0)
191 end_job_control ();
192#endif /* JOB_CONTROL */
193
194 shell_execve (command, args, env);
195
196 /* We have to set this to NULL because shell_execve has called realloc()
197 to stuff more items at the front of the array, which may have caused
198 the memory to be freed by realloc(). We don't want to free it twice. */
199 args = (char **)NULL;
200 if (cleanenv == 0)
201 adjust_shell_level (1);
202
203 if (executable_file (command) == 0)
204 {
205 builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
206 exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
207 }
208 else
209 file_error (command);
210
211failed_exec:
212 FREE (command);
213
214 if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
215 exit_shell (exit_value);
216
217 if (args)
218 strvec_dispose (args);
219
220 initialize_traps ();
221 initialize_signals (1);
222
223#if defined (JOB_CONTROL)
224 if (interactive_shell || job_control)
225 restart_job_control ();
226#endif /* JOB_CONTROL */
227
228 return (exit_value);
229}
Note: See TracBrowser for help on using the repository browser.