LCOV - code coverage report
Current view: top level - builtins - exit.def (source / functions) Hit Total Coverage
Test: cov-sh.info Lines: 16 39 41.0 %
Date: 2020-10-29 14:49:55 Functions: 3 4 75.0 %

          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 : }

Generated by: LCOV version 1.14.0.6.4058