Imported from ../bash-2.0.tar.gz.
[platform/upstream/bash.git] / builtins / exit.def
1 This file is exit.def, from which is created exit.c.
2 It implements the builtins "exit", and "logout" 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 exit.c
23
24 $BUILTIN exit
25 $FUNCTION exit_builtin
26 $SHORT_DOC exit [n]
27 Exit the shell with a status of N.  If N is omitted, the exit status
28 is that of the last command executed.
29 $END
30
31 #include <config.h>
32
33 #include <sys/types.h>
34 #include <stdio.h>
35
36 #if defined (HAVE_UNISTD_H)
37 #  include <unistd.h>
38 #endif
39
40 #include "../shell.h"
41 #include "../jobs.h"
42
43 #include "common.h"
44 #include "builtext.h"   /* for jobs_builtin */
45
46 extern int interactive, login_shell;
47 extern int last_command_exit_value;
48
49 static int exit_or_logout ();
50 static int sourced_logout;
51
52 int
53 exit_builtin (list)
54      WORD_LIST *list;
55 {
56   if (interactive)
57     {
58       fprintf (stderr, login_shell ? "logout\n" : "exit\n");
59       fflush (stderr);
60     }
61
62   return (exit_or_logout (list));
63 }
64
65 $BUILTIN logout
66 $FUNCTION logout_builtin
67 $SHORT_DOC logout
68 Logout of a login shell.
69 $END
70
71 /* How to logout. */
72 int
73 logout_builtin (list)
74      WORD_LIST *list;
75 {
76   if (login_shell == 0 && interactive)
77     {
78       builtin_error ("not login shell: use `exit'");
79       return (EXECUTION_FAILURE);
80     }
81   else
82     return (exit_or_logout (list));
83 }
84
85 /* Clean up work for exiting or logging out. */
86 Function *last_shell_builtin = (Function *)NULL;
87 Function *this_shell_builtin = (Function *)NULL;
88
89 static int
90 exit_or_logout (list)
91      WORD_LIST *list;
92 {
93   int exit_value;
94
95 #if defined (JOB_CONTROL)
96   int exit_immediate_okay;
97
98   exit_immediate_okay = (interactive  == 0 ||
99                          last_shell_builtin == exit_builtin ||
100                          last_shell_builtin == logout_builtin ||
101                          last_shell_builtin == jobs_builtin);
102
103   /* Check for stopped jobs if the user wants to. */
104   if (!exit_immediate_okay)
105     {
106       register int i;
107       for (i = 0; i < job_slots; i++)
108         if (jobs[i] && STOPPED (i))
109           {
110             fprintf (stderr, "There are stopped jobs.\n");
111
112             /* This is NOT superfluous because EOF can get here without
113                going through the command parser.  Set both last and this
114                so that either `exit', `logout', or ^D will work to exit
115                immediately if nothing intervenes. */
116             this_shell_builtin = last_shell_builtin = exit_builtin;
117             return (EXECUTION_FAILURE);
118           }
119     }
120 #endif /* JOB_CONTROL */
121
122   /* Get return value if present.  This means that you can type
123      `logout 5' to a shell, and it returns 5. */
124   exit_value = list ? get_numeric_arg (list) : last_command_exit_value;
125
126   /* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
127   if (login_shell && sourced_logout++ == 0)
128     {
129       maybe_execute_file ("~/.bash_logout", 1);
130 #ifdef SYS_BASH_LOGOUT
131       maybe_execute_file (SYS_BASH_LOGOUT, 1);
132 #endif
133     }
134
135   last_command_exit_value = exit_value;
136
137   /* Exit the program. */
138   jump_to_top_level (EXITPROG);
139   /*NOTREACHED*/
140 }