Line data Source code
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-2009 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 exit.c 22 : 23 : $BUILTIN exit 24 : $FUNCTION exit_builtin 25 : $SHORT_DOC exit [n] 26 : Exit the shell. 27 : 28 : Exits the shell with a status of N. If N is omitted, the exit status 29 : is that of the last command executed. 30 : $END 31 : 32 : #include <config.h> 33 : 34 : #include "../bashtypes.h" 35 : #include <stdio.h> 36 : 37 : #if defined (HAVE_UNISTD_H) 38 : # include <unistd.h> 39 : #endif 40 : 41 : #include "../bashintl.h" 42 : 43 : #include "../shell.h" 44 : #include "../jobs.h" 45 : 46 : #include "common.h" 47 : #include "builtext.h" /* for jobs_builtin */ 48 : 49 : extern int check_jobs_at_exit; 50 : extern int last_command_exit_value; 51 : extern int running_trap, trap_saved_exit_value; 52 : extern int subshell_environment; 53 : extern sh_builtin_func_t *this_shell_builtin; 54 : extern sh_builtin_func_t *last_shell_builtin; 55 : 56 : static int exit_or_logout __P((WORD_LIST *)); 57 : static int sourced_logout; 58 : 59 : int 60 7335361 : exit_builtin (list) 61 : WORD_LIST *list; 62 : { 63 7335361 : CHECK_HELPOPT (list); 64 : 65 7335361 : if (interactive) 66 : { 67 0 : fprintf (stderr, login_shell ? _("logout\n") : "exit\n"); 68 0 : fflush (stderr); 69 : } 70 : 71 7335361 : return (exit_or_logout (list)); 72 : } 73 : 74 : $BUILTIN logout 75 : $FUNCTION logout_builtin 76 : $SHORT_DOC logout [n] 77 : Exit a login shell. 78 : 79 : Exits a login shell with exit status N. Returns an error if not executed 80 : in a login shell. 81 : $END 82 : 83 : /* How to logout. */ 84 : int 85 0 : logout_builtin (list) 86 : WORD_LIST *list; 87 : { 88 0 : CHECK_HELPOPT (list); 89 : 90 0 : if (login_shell == 0 /* && interactive */) 91 : { 92 0 : builtin_error (_("not login shell: use `exit'")); 93 0 : return (EXECUTION_FAILURE); 94 : } 95 : else 96 0 : return (exit_or_logout (list)); 97 : } 98 : 99 : static int 100 7335361 : exit_or_logout (list) 101 : WORD_LIST *list; 102 : { 103 7335361 : int exit_value; 104 : 105 : #if defined (JOB_CONTROL) 106 7335361 : int exit_immediate_okay, stopmsg; 107 : 108 7335361 : exit_immediate_okay = (interactive == 0 || 109 0 : last_shell_builtin == exit_builtin || 110 7335361 : last_shell_builtin == logout_builtin || 111 : last_shell_builtin == jobs_builtin); 112 : 113 : /* Check for stopped jobs if the user wants to. */ 114 : if (exit_immediate_okay == 0) 115 : { 116 : register int i; 117 0 : for (i = stopmsg = 0; i < js.j_jobslots; i++) 118 0 : if (jobs[i] && STOPPED (i)) 119 : stopmsg = JSTOPPED; 120 0 : else if (check_jobs_at_exit && stopmsg == 0 && jobs[i] && RUNNING (i)) 121 0 : stopmsg = JRUNNING; 122 : 123 0 : if (stopmsg == JSTOPPED) 124 0 : fprintf (stderr, _("There are stopped jobs.\n")); 125 0 : else if (stopmsg == JRUNNING) 126 0 : fprintf (stderr, _("There are running jobs.\n")); 127 : 128 0 : if (stopmsg && check_jobs_at_exit) 129 0 : list_all_jobs (JLIST_STANDARD); 130 : 131 0 : if (stopmsg) 132 : { 133 : /* This is NOT superfluous because EOF can get here without 134 : going through the command parser. Set both last and this 135 : so that either `exit', `logout', or ^D will work to exit 136 : immediately if nothing intervenes. */ 137 0 : this_shell_builtin = last_shell_builtin = exit_builtin; 138 0 : return (EXECUTION_FAILURE); 139 : } 140 : } 141 : #endif /* JOB_CONTROL */ 142 : 143 : /* Get return value if present. This means that you can type 144 : `logout 5' to a shell, and it returns 5. */ 145 : 146 : /* If we're running the exit trap (running_trap == 1, since running_trap 147 : gets set to SIG+1), and we don't have a argument given to `exit' 148 : (list == 0), use the exit status we saved before running the trap 149 : commands (trap_saved_exit_value). */ 150 7335361 : exit_value = (running_trap == 1 && list == 0) ? trap_saved_exit_value : get_exitstat (list); 151 : 152 7335238 : bash_logout (); 153 : 154 7335238 : last_command_exit_value = exit_value; 155 : 156 : /* Exit the program. */ 157 7335238 : jump_to_top_level (EXITPROG); 158 : /*NOTREACHED*/ 159 : } 160 : 161 : void 162 7335238 : bash_logout () 163 : { 164 : /* Run our `~/.bash_logout' file if it exists, and this is a login shell. */ 165 7335238 : if (login_shell && sourced_logout++ == 0 && subshell_environment == 0) 166 : { 167 0 : maybe_execute_file ("~/.bash_logout", 1); 168 : #ifdef SYS_BASH_LOGOUT 169 : maybe_execute_file (SYS_BASH_LOGOUT, 1); 170 : #endif 171 : } 172 7335238 : }