Imported from ../bash-2.05a.tar.gz.
[platform/upstream/bash.git] / builtins / exec.def
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, 1989, 1991 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 it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING.  If not, write to the Free Software
20 Foundation, 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 ...]
27 Exec FILE, replacing this shell with the specified program.
28 If FILE is not specified, the redirections take effect in this
29 shell.  If the first argument is `-l', then place a dash in the
30 zeroth arg passed to FILE, as login does.  If the `-c' option
31 is supplied, FILE is executed with a null environment.  The `-a'
32 option means to make set argv[0] of the executed process to NAME.
33 If the file cannot be executed and the shell is not interactive,
34 then 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
50 #include "../shell.h"
51 #include "../execute_cmd.h"
52 #include "../findcmd.h"
53 #if defined (JOB_CONTROL)
54 #  include "../jobs.h"
55 #endif
56 #include "../flags.h"
57 #include "../trap.h"
58 #if defined (HISTORY)
59 #  include "../bashhist.h"
60 #endif
61 #include "common.h"
62 #include "bashgetopt.h"
63
64 /* Not all systems declare ERRNO in errno.h... and some systems #define it! */
65 #if !defined (errno)
66 extern int errno;
67 #endif /* !errno */
68
69 extern int subshell_environment;
70 extern REDIRECT *redirection_undo_list;
71
72 int 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. */
76 static char *
77 mkdashname (name)
78      char *name;
79 {
80   char *ret;
81
82   ret = (char *)xmalloc (2 + strlen (name));
83   ret[0] = '-';
84   strcpy (ret + 1, name);
85   return ret;
86 }
87
88 int
89 exec_builtin (list)
90      WORD_LIST *list;
91 {
92   int exit_value = EXECUTION_FAILURE;
93   int cleanenv, login, opt;
94   char *argv0, *command, **args, **env, *newname, *com2;
95
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;
119
120   /* First, let the redirections remain. */
121   dispose_redirects (redirection_undo_list);
122   redirection_undo_list = (REDIRECT *)NULL;
123
124   if (list == 0)
125     return (EXECUTION_SUCCESS);
126
127 #if defined (RESTRICTED_SHELL)
128   if (restricted)
129     {
130       builtin_error ("restricted");
131       return (EXECUTION_FAILURE);
132     }
133 #endif /* RESTRICTED_SHELL */
134
135   args = word_list_to_argv (list, 1, 0, (int *)NULL);
136
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]);
139
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     }
146
147   com2 = full_pathname (command);
148   if (com2)
149     {
150       if (command != args[0])
151         free (command);
152       command = com2;
153     }
154
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     }
166
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);
172
173   if (cleanenv)
174     env = (char **)NULL;
175   else
176     {   
177       maybe_make_export_env ();
178       env = export_env;
179     }
180
181 #if defined (HISTORY)
182   if (interactive_shell && subshell_environment == 0)
183     maybe_save_shell_history ();
184 #endif /* HISTORY */
185
186   restore_original_signals ();
187
188 #if defined (JOB_CONTROL)
189   if (subshell_environment == 0)
190     end_job_control ();
191 #endif /* JOB_CONTROL */
192
193   shell_execve (command, args, env);
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;
199   if (cleanenv == 0)
200     adjust_shell_level (1);
201
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);
209
210 failed_exec:
211   if (command)
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     free_array (args);
219
220   initialize_traps ();
221   reinitialize_signals ();
222
223 #if defined (JOB_CONTROL)
224   restart_job_control ();
225 #endif /* JOB_CONTROL */
226
227   return (exit_value);
228 }