Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/bash/src/builtins/exec.def |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | This file is exec.def, from which is created exec.c. | - | ||||||||||||||||||
2 | It implements the builtin "exec" in Bash. | - | ||||||||||||||||||
3 | - | |||||||||||||||||||
4 | Copyright (C) 1987-2015 Free Software Foundation, Inc. | - | ||||||||||||||||||
5 | - | |||||||||||||||||||
6 | This file is part of GNU Bash, the Bourne Again SHell. | - | ||||||||||||||||||
7 | - | |||||||||||||||||||
8 | Bash is free software: you can redistribute it and/or modify | - | ||||||||||||||||||
9 | it under the terms of the GNU General Public License as published by | - | ||||||||||||||||||
10 | the Free Software Foundation, either version 3 of the License, or | - | ||||||||||||||||||
11 | (at your option) any later version. | - | ||||||||||||||||||
12 | - | |||||||||||||||||||
13 | Bash is distributed in the hope that it will be useful, | - | ||||||||||||||||||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | ||||||||||||||||||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | ||||||||||||||||||
16 | GNU General Public License for more details. | - | ||||||||||||||||||
17 | - | |||||||||||||||||||
18 | You should have received a copy of the GNU General Public License | - | ||||||||||||||||||
19 | along with Bash. If not, see <http://www.gnu.org/licenses/>. | - | ||||||||||||||||||
20 | - | |||||||||||||||||||
21 | $PRODUCES exec.c | - | ||||||||||||||||||
22 | - | |||||||||||||||||||
23 | $BUILTIN exec | - | ||||||||||||||||||
24 | $FUNCTION exec_builtin | - | ||||||||||||||||||
25 | $SHORT_DOC exec [-cl] [-a name] [command [arguments ...]] [redirection ...] | - | ||||||||||||||||||
26 | Replace the shell with the given command. | - | ||||||||||||||||||
27 | - | |||||||||||||||||||
28 | Execute COMMAND, replacing this shell with the specified program. | - | ||||||||||||||||||
29 | ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified, | - | ||||||||||||||||||
30 | any redirections take effect in the current shell. | - | ||||||||||||||||||
31 | - | |||||||||||||||||||
32 | Options: | - | ||||||||||||||||||
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 | - | |||||||||||||||||||
37 | If the command cannot be executed, a non-interactive shell exits, unless | - | ||||||||||||||||||
38 | the shell option `execfail' is set. | - | ||||||||||||||||||
39 | - | |||||||||||||||||||
40 | Exit Status: | - | ||||||||||||||||||
41 | Returns success unless COMMAND is not found or a redirection error occurs. | - | ||||||||||||||||||
42 | $END | - | ||||||||||||||||||
43 | - | |||||||||||||||||||
44 | #include <config.h> | - | ||||||||||||||||||
45 | - | |||||||||||||||||||
46 | #include "../bashtypes.h" | - | ||||||||||||||||||
47 | #include "posixstat.h" | - | ||||||||||||||||||
48 | #include <signal.h> | - | ||||||||||||||||||
49 | #include <errno.h> | - | ||||||||||||||||||
50 | - | |||||||||||||||||||
51 | #if defined (HAVE_UNISTD_H) | - | ||||||||||||||||||
52 | # include <unistd.h> | - | ||||||||||||||||||
53 | #endif | - | ||||||||||||||||||
54 | - | |||||||||||||||||||
55 | #include "../bashansi.h" | - | ||||||||||||||||||
56 | #include "../bashintl.h" | - | ||||||||||||||||||
57 | - | |||||||||||||||||||
58 | #include "../shell.h" | - | ||||||||||||||||||
59 | #include "../execute_cmd.h" | - | ||||||||||||||||||
60 | #include "../findcmd.h" | - | ||||||||||||||||||
61 | #if defined (JOB_CONTROL) | - | ||||||||||||||||||
62 | # include "../jobs.h" | - | ||||||||||||||||||
63 | #endif | - | ||||||||||||||||||
64 | #include "../flags.h" | - | ||||||||||||||||||
65 | #include "../trap.h" | - | ||||||||||||||||||
66 | #if defined (HISTORY) | - | ||||||||||||||||||
67 | # include "../bashhist.h" | - | ||||||||||||||||||
68 | #endif | - | ||||||||||||||||||
69 | #include "common.h" | - | ||||||||||||||||||
70 | #include "bashgetopt.h" | - | ||||||||||||||||||
71 | - | |||||||||||||||||||
72 | /* Not all systems declare ERRNO in errno.h... and some systems #define it! */ | - | ||||||||||||||||||
73 | #if !defined (errno) | - | ||||||||||||||||||
74 | extern int errno; | - | ||||||||||||||||||
75 | #endif /* !errno */ | - | ||||||||||||||||||
76 | - | |||||||||||||||||||
77 | extern REDIRECT *redirection_undo_list; | - | ||||||||||||||||||
78 | extern char *exec_argv0; | - | ||||||||||||||||||
79 | - | |||||||||||||||||||
80 | int 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. */ | - | ||||||||||||||||||
84 | static char * | - | ||||||||||||||||||
85 | mkdashname (name) | - | ||||||||||||||||||
86 | char *name; | - | ||||||||||||||||||
87 | { | - | ||||||||||||||||||
88 | char *ret; | - | ||||||||||||||||||
89 | - | |||||||||||||||||||
90 | ret = (char *)xmalloc (2 + strlen (name)); | - | ||||||||||||||||||
91 | ret[0] = '-'; | - | ||||||||||||||||||
92 | strcpy (ret + 1, name); | - | ||||||||||||||||||
93 | return ret; never executed: return ret; | 0 | ||||||||||||||||||
94 | } | - | ||||||||||||||||||
95 | - | |||||||||||||||||||
96 | int | - | ||||||||||||||||||
97 | exec_builtin (list) | - | ||||||||||||||||||
98 | WORD_LIST *list; | - | ||||||||||||||||||
99 | { | - | ||||||||||||||||||
100 | int exit_value = EXECUTION_FAILURE; | - | ||||||||||||||||||
101 | int cleanenv, login, opt; | - | ||||||||||||||||||
102 | char *argv0, *command, **args, **env, *newname, *com2; | - | ||||||||||||||||||
103 | - | |||||||||||||||||||
104 | cleanenv = login = 0; | - | ||||||||||||||||||
105 | exec_argv0 = argv0 = (char *)NULL; | - | ||||||||||||||||||
106 | - | |||||||||||||||||||
107 | reset_internal_getopt (); | - | ||||||||||||||||||
108 | while ((opt = internal_getopt (list, "cla:")) != -1)
| 5-262 | ||||||||||||||||||
109 | { | - | ||||||||||||||||||
110 | switch (opt) | - | ||||||||||||||||||
111 | { | - | ||||||||||||||||||
112 | case 'c': never executed: case 'c': | 0 | ||||||||||||||||||
113 | cleanenv = 1; | - | ||||||||||||||||||
114 | break; never executed: break; | 0 | ||||||||||||||||||
115 | case 'l': never executed: case 'l': | 0 | ||||||||||||||||||
116 | login = 1; | - | ||||||||||||||||||
117 | break; never executed: break; | 0 | ||||||||||||||||||
118 | case 'a': never executed: case 'a': | 0 | ||||||||||||||||||
119 | argv0 = list_optarg; | - | ||||||||||||||||||
120 | break; never executed: break; | 0 | ||||||||||||||||||
121 | CASE_HELPOPT; never executed: return (258); never executed: case -99: | 0 | ||||||||||||||||||
122 | default: executed 5 times by 1 test: default: Executed by:
| 5 | ||||||||||||||||||
123 | builtin_usage (); | - | ||||||||||||||||||
124 | return (EX_USAGE); executed 5 times by 1 test: return (258); Executed by:
| 5 | ||||||||||||||||||
125 | } | - | ||||||||||||||||||
126 | } | - | ||||||||||||||||||
127 | list = loptend; | - | ||||||||||||||||||
128 | - | |||||||||||||||||||
129 | /* First, let the redirections remain. */ | - | ||||||||||||||||||
130 | dispose_redirects (redirection_undo_list); | - | ||||||||||||||||||
131 | redirection_undo_list = (REDIRECT *)NULL; | - | ||||||||||||||||||
132 | - | |||||||||||||||||||
133 | if (list == 0)
| 3-259 | ||||||||||||||||||
134 | return (EXECUTION_SUCCESS); executed 259 times by 1 test: return (0); Executed by:
| 259 | ||||||||||||||||||
135 | - | |||||||||||||||||||
136 | #if defined (RESTRICTED_SHELL) | - | ||||||||||||||||||
137 | if (restricted)
| 1-2 | ||||||||||||||||||
138 | { | - | ||||||||||||||||||
139 | sh_restricted ((char *)NULL); | - | ||||||||||||||||||
140 | return (EXECUTION_FAILURE); executed 1 time by 1 test: return (1); Executed by:
| 1 | ||||||||||||||||||
141 | } | - | ||||||||||||||||||
142 | #endif /* RESTRICTED_SHELL */ | - | ||||||||||||||||||
143 | - | |||||||||||||||||||
144 | args = strvec_from_word_list (list, 1, 0, (int *)NULL); | - | ||||||||||||||||||
145 | env = (char **)0; | - | ||||||||||||||||||
146 | - | |||||||||||||||||||
147 | /* A command with a slash anywhere in its name is not looked up in $PATH. */ | - | ||||||||||||||||||
148 | command = absolute_program (args[0]) ? args[0] : search_for_command (args[0], 1);
| 0-2 | ||||||||||||||||||
149 | - | |||||||||||||||||||
150 | if (command == 0)
| 0-2 | ||||||||||||||||||
151 | { | - | ||||||||||||||||||
152 | if (file_isdir (args[0]))
| 0 | ||||||||||||||||||
153 | { | - | ||||||||||||||||||
154 | #if defined (EISDIR) | - | ||||||||||||||||||
155 | builtin_error (_("%s: cannot execute: %s"), args[0], strerror (EISDIR)); | - | ||||||||||||||||||
156 | #else | - | ||||||||||||||||||
157 | builtin_error (_("%s: cannot execute: %s"), args[0], strerror (errno)); | - | ||||||||||||||||||
158 | #endif | - | ||||||||||||||||||
159 | exit_value = EX_NOEXEC; | - | ||||||||||||||||||
160 | } never executed: end of block | 0 | ||||||||||||||||||
161 | else | - | ||||||||||||||||||
162 | { | - | ||||||||||||||||||
163 | sh_notfound (args[0]); | - | ||||||||||||||||||
164 | exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */ | - | ||||||||||||||||||
165 | } never executed: end of block | 0 | ||||||||||||||||||
166 | goto failed_exec; never executed: goto failed_exec; | 0 | ||||||||||||||||||
167 | } | - | ||||||||||||||||||
168 | - | |||||||||||||||||||
169 | com2 = full_pathname (command); | - | ||||||||||||||||||
170 | if (com2)
| 0-2 | ||||||||||||||||||
171 | { | - | ||||||||||||||||||
172 | if (command != args[0])
| 0-2 | ||||||||||||||||||
173 | free (command); never executed: sh_xfree((command), "./exec.def", 173); | 0 | ||||||||||||||||||
174 | command = com2; | - | ||||||||||||||||||
175 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
176 | - | |||||||||||||||||||
177 | if (argv0)
| 0-2 | ||||||||||||||||||
178 | { | - | ||||||||||||||||||
179 | free (args[0]); | - | ||||||||||||||||||
180 | args[0] = login ? mkdashname (argv0) : savestring (argv0);
| 0 | ||||||||||||||||||
181 | exec_argv0 = savestring (args[0]); | - | ||||||||||||||||||
182 | } never executed: end of block | 0 | ||||||||||||||||||
183 | else if (login)
| 0-2 | ||||||||||||||||||
184 | { | - | ||||||||||||||||||
185 | newname = mkdashname (args[0]); | - | ||||||||||||||||||
186 | free (args[0]); | - | ||||||||||||||||||
187 | args[0] = newname; | - | ||||||||||||||||||
188 | } never executed: end of block | 0 | ||||||||||||||||||
189 | - | |||||||||||||||||||
190 | /* Decrement SHLVL by 1 so a new shell started here has the same value, | - | ||||||||||||||||||
191 | preserving the appearance. After we do that, we need to change the | - | ||||||||||||||||||
192 | exported environment to include the new value. If we've already forked | - | ||||||||||||||||||
193 | and are in a subshell, we don't want to decrement the shell level, | - | ||||||||||||||||||
194 | since we are `increasing' the level */ | - | ||||||||||||||||||
195 | - | |||||||||||||||||||
196 | if (cleanenv == 0 && (subshell_environment & SUBSHELL_PAREN) == 0)
| 0-2 | ||||||||||||||||||
197 | adjust_shell_level (-1); executed 1 time by 1 test: adjust_shell_level (-1); Executed by:
| 1 | ||||||||||||||||||
198 | - | |||||||||||||||||||
199 | if (cleanenv)
| 0-2 | ||||||||||||||||||
200 | { | - | ||||||||||||||||||
201 | env = strvec_create (1); | - | ||||||||||||||||||
202 | env[0] = (char *)0; | - | ||||||||||||||||||
203 | } never executed: end of block | 0 | ||||||||||||||||||
204 | else | - | ||||||||||||||||||
205 | { | - | ||||||||||||||||||
206 | maybe_make_export_env (); | - | ||||||||||||||||||
207 | env = export_env; | - | ||||||||||||||||||
208 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
209 | - | |||||||||||||||||||
210 | #if defined (HISTORY) | - | ||||||||||||||||||
211 | if (interactive_shell && subshell_environment == 0)
| 0-2 | ||||||||||||||||||
212 | maybe_save_shell_history (); never executed: maybe_save_shell_history (); | 0 | ||||||||||||||||||
213 | #endif /* HISTORY */ | - | ||||||||||||||||||
214 | - | |||||||||||||||||||
215 | restore_original_signals (); | - | ||||||||||||||||||
216 | - | |||||||||||||||||||
217 | #if defined (JOB_CONTROL) | - | ||||||||||||||||||
218 | if (subshell_environment == 0)
| 1 | ||||||||||||||||||
219 | end_job_control (); executed 1 time by 1 test: end_job_control (); Executed by:
| 1 | ||||||||||||||||||
220 | if (interactive || job_control)
| 0-2 | ||||||||||||||||||
221 | default_tty_job_signals (); /* undo initialize_job_signals */ never executed: default_tty_job_signals (); | 0 | ||||||||||||||||||
222 | #endif /* JOB_CONTROL */ | - | ||||||||||||||||||
223 | - | |||||||||||||||||||
224 | exit_value = shell_execve (command, args, env); | - | ||||||||||||||||||
225 | - | |||||||||||||||||||
226 | /* We have to set this to NULL because shell_execve has called realloc() | - | ||||||||||||||||||
227 | to stuff more items at the front of the array, which may have caused | - | ||||||||||||||||||
228 | the memory to be freed by realloc(). We don't want to free it twice. */ | - | ||||||||||||||||||
229 | args = (char **)NULL; | - | ||||||||||||||||||
230 | if (cleanenv == 0)
| 0-2 | ||||||||||||||||||
231 | adjust_shell_level (1); executed 2 times by 1 test: adjust_shell_level (1); Executed by:
| 2 | ||||||||||||||||||
232 | - | |||||||||||||||||||
233 | if (exit_value == EX_NOTFOUND) /* no duplicate error message */
| 0-2 | ||||||||||||||||||
234 | goto failed_exec; executed 2 times by 1 test: goto failed_exec; Executed by:
| 2 | ||||||||||||||||||
235 | else if (executable_file (command) == 0)
| 0 | ||||||||||||||||||
236 | { | - | ||||||||||||||||||
237 | builtin_error (_("%s: cannot execute: %s"), command, strerror (errno)); | - | ||||||||||||||||||
238 | exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */ | - | ||||||||||||||||||
239 | } never executed: end of block | 0 | ||||||||||||||||||
240 | else | - | ||||||||||||||||||
241 | file_error (command); never executed: file_error (command); | 0 | ||||||||||||||||||
242 | - | |||||||||||||||||||
243 | failed_exec: code before this statement never executed: failed_exec: | 0 | ||||||||||||||||||
244 | FREE (command); executed 2 times by 1 test: sh_xfree((command), "./exec.def", 244); Executed by:
| 0-2 | ||||||||||||||||||
245 | - | |||||||||||||||||||
246 | if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
| 0-1 | ||||||||||||||||||
247 | exit_shell (exit_value); executed 1 time by 1 test: exit_shell (exit_value); Executed by:
| 1 | ||||||||||||||||||
248 | - | |||||||||||||||||||
249 | if (args)
| 0-1 | ||||||||||||||||||
250 | strvec_dispose (args); never executed: strvec_dispose (args); | 0 | ||||||||||||||||||
251 | - | |||||||||||||||||||
252 | if (env && env != export_env)
| 0-1 | ||||||||||||||||||
253 | strvec_dispose (env); never executed: strvec_dispose (env); | 0 | ||||||||||||||||||
254 | - | |||||||||||||||||||
255 | initialize_traps (); | - | ||||||||||||||||||
256 | initialize_signals (1); | - | ||||||||||||||||||
257 | - | |||||||||||||||||||
258 | #if defined (JOB_CONTROL) | - | ||||||||||||||||||
259 | if (interactive_shell || job_control)
| 0-1 | ||||||||||||||||||
260 | restart_job_control (); never executed: restart_job_control (); | 0 | ||||||||||||||||||
261 | #endif /* JOB_CONTROL */ | - | ||||||||||||||||||
262 | - | |||||||||||||||||||
263 | return (exit_value); executed 1 time by 1 test: return (exit_value); Executed by:
| 1 | ||||||||||||||||||
264 | } | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |