blob: 3a4850963d5ae8d97b170dca484c4586ebbac1f0 [file] [log] [blame]
Dan Pasanenc6e37862014-10-02 14:08:59 -05001/* exit.c, created from exit.def. */
2#line 22 "./exit.def"
3
4#line 31 "./exit.def"
5
6#include <config.h>
7
8#include "../bashtypes.h"
9#include <stdio.h>
10
11#if defined (HAVE_UNISTD_H)
12# include <unistd.h>
13#endif
14
15#include "../bashintl.h"
16
17#include "../shell.h"
18#include "../jobs.h"
19
20#include "common.h"
21#include "builtext.h" /* for jobs_builtin */
22
23extern int check_jobs_at_exit;
24extern int last_command_exit_value;
25extern int running_trap, trap_saved_exit_value;
26extern int subshell_environment;
27extern sh_builtin_func_t *this_shell_builtin;
28extern sh_builtin_func_t *last_shell_builtin;
29
30static int exit_or_logout __P((WORD_LIST *));
31static int sourced_logout;
32
33int
34exit_builtin (list)
35 WORD_LIST *list;
36{
37 if (interactive)
38 {
39 fprintf (stderr, login_shell ? _("logout\n") : "exit\n");
40 fflush (stderr);
41 }
42
43 return (exit_or_logout (list));
44}
45
46#line 80 "./exit.def"
47
48/* How to logout. */
49int
50logout_builtin (list)
51 WORD_LIST *list;
52{
53 if (login_shell == 0 /* && interactive */)
54 {
55 builtin_error (_("not login shell: use `exit'"));
56 return (EXECUTION_FAILURE);
57 }
58 else
59 return (exit_or_logout (list));
60}
61
62static int
63exit_or_logout (list)
64 WORD_LIST *list;
65{
66 int exit_value;
67
68#if defined (JOB_CONTROL)
69 int exit_immediate_okay, stopmsg;
70
71 exit_immediate_okay = (interactive == 0 ||
72 last_shell_builtin == exit_builtin ||
73 last_shell_builtin == logout_builtin ||
74 last_shell_builtin == jobs_builtin);
75
76 /* Check for stopped jobs if the user wants to. */
77 if (exit_immediate_okay == 0)
78 {
79 register int i;
80 for (i = stopmsg = 0; i < js.j_jobslots; i++)
81 if (jobs[i] && STOPPED (i))
82 stopmsg = JSTOPPED;
83 else if (check_jobs_at_exit && stopmsg == 0 && jobs[i] && RUNNING (i))
84 stopmsg = JRUNNING;
85
86 if (stopmsg == JSTOPPED)
87 fprintf (stderr, _("There are stopped jobs.\n"));
88 else if (stopmsg == JRUNNING)
89 fprintf (stderr, _("There are running jobs.\n"));
90
91 if (stopmsg && check_jobs_at_exit)
92 list_all_jobs (JLIST_STANDARD);
93
94 if (stopmsg)
95 {
96 /* This is NOT superfluous because EOF can get here without
97 going through the command parser. Set both last and this
98 so that either `exit', `logout', or ^D will work to exit
99 immediately if nothing intervenes. */
100 this_shell_builtin = last_shell_builtin = exit_builtin;
101 return (EXECUTION_FAILURE);
102 }
103 }
104#endif /* JOB_CONTROL */
105
106 /* Get return value if present. This means that you can type
107 `logout 5' to a shell, and it returns 5. */
108
109 /* If we're running the exit trap (running_trap == 1, since running_trap
110 gets set to SIG+1), and we don't have a argument given to `exit'
111 (list == 0), use the exit status we saved before running the trap
112 commands (trap_saved_exit_value). */
113 exit_value = (running_trap == 1 && list == 0) ? trap_saved_exit_value : get_exitstat (list);
114
115 bash_logout ();
116
117 last_command_exit_value = exit_value;
118
119 /* Exit the program. */
120 jump_to_top_level (EXITPROG);
121 /*NOTREACHED*/
122}
123
124void
125bash_logout ()
126{
127 /* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
128 if (login_shell && sourced_logout++ == 0 && subshell_environment == 0)
129 {
130 maybe_execute_file ("~/.bash_logout", 1);
131#ifdef SYS_BASH_LOGOUT
132 maybe_execute_file (SYS_BASH_LOGOUT, 1);
133#endif
134 }
135}