Imported from ../bash-1.14.7.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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 $PRODUCES exec.c
23
24 $BUILTIN exec
25 $FUNCTION exec_builtin
26 $SHORT_DOC exec [ [-] 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 `-', then place a dash in the
30 zeroth arg passed to FILE.  If the file cannot be exec'ed and
31 the shell is not interactive, then the shell exits, unless the
32 shell variable "no_exit_on_failed_exec" exists.
33 $END
34
35 #include "../shell.h"
36 #include <sys/types.h>
37 #include "../posixstat.h"
38 #include <signal.h>
39 #include <errno.h>
40
41 #include "../execute_cmd.h"
42 #include "common.h"
43 #include "../flags.h"
44
45 /* Not all systems declare ERRNO in errno.h... and some systems #define it! */
46 #if !defined (errno)
47 extern int errno;
48 #endif /* !errno */
49 extern int interactive, subshell_environment;
50 extern REDIRECT *redirection_undo_list;
51
52 int
53 exec_builtin (list)
54      WORD_LIST *list;
55 {
56   int exit_value = EXECUTION_FAILURE;
57
58   maybe_make_export_env ();
59
60   /* First, let the redirections remain. */
61   dispose_redirects (redirection_undo_list);
62   redirection_undo_list = (REDIRECT *)NULL;
63
64   if (!list)
65     return (EXECUTION_SUCCESS);
66   else
67     {
68       /* Otherwise, execve the new command with args. */
69       char *command, **args;
70       int dash_name = 0;
71
72       if (list->word->word[0] == '-' && !list->word->word[1])
73         {
74           /* The user would like to exec this command as if it was a
75              login command.  Do so. */
76           list = list->next;
77           dash_name++;
78         }
79
80       if (!list)
81         return (EXECUTION_SUCCESS);
82
83 #if defined (RESTRICTED_SHELL)
84       if (restricted)
85         {
86           builtin_error ("restricted");
87           return (EXECUTION_FAILURE);
88         }
89 #endif /* RESTRICTED_SHELL */
90
91       args = make_word_array (list);
92
93       /* A command with a slash anywhere in its name is not looked up in
94          the search path. */
95       if (absolute_program (args[0]))
96         command = args[0];
97       else
98         command = find_user_command (args[0]);
99       if (!command)
100         {
101           builtin_error ("%s: not found", args[0]);
102           exit_value = EX_NOTFOUND;     /* As per Posix.2, 3.14.6 */
103           goto failed_exec;
104         }
105
106       command = full_pathname (command);
107       /* If the user wants this to look like a login shell, then
108          prepend a `-' onto the first argument (argv[0]). */
109       if (dash_name)
110         {
111           char *new_name = xmalloc (2 + strlen (args[0]));
112           new_name[0] = '-';
113           strcpy (new_name + 1, args[0]);
114           free (args[0]);
115           args[0] = new_name;
116         }
117
118       /* Decrement SHLVL by 1 so a new shell started here has the same value,
119          preserving the appearance.  After we do that, we need to change the
120          exported environment to include the new value. */
121       adjust_shell_level (-1);
122       maybe_make_export_env ();
123
124 #if defined (HISTORY)
125       maybe_save_shell_history ();
126 #endif /* HISTORY */
127       restore_original_signals ();
128
129 #if defined (JOB_CONTROL)
130       if (subshell_environment == 0)
131         end_job_control ();
132 #endif /* JOB_CONTROL */
133
134       shell_execve (command, args, export_env);
135
136       adjust_shell_level (1);
137
138       if (!executable_file (command))
139         {
140           builtin_error ("%s: cannot execute: %s", command, strerror (errno));
141           exit_value = EX_NOEXEC;       /* As per Posix.2, 3.14.6 */
142         }
143       else
144         file_error (command);
145
146   failed_exec:
147       if (command)
148         free (command);
149
150       if (subshell_environment ||
151           (!interactive && !find_variable ("no_exit_on_failed_exec")))
152         exit (exit_value);
153
154       initialize_traps ();
155       reinitialize_signals ();
156
157 #if defined (JOB_CONTROL)
158       restart_job_control ();
159 #endif /* JOB_CONTROL */
160
161       return (exit_value);
162     }
163 }