Line data Source code
1 : This file is suspend.def, from which is created suspend.c. 2 : It implements the builtin "suspend" in Bash. 3 : 4 : Copyright (C) 1987-2015 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 suspend.c 22 : 23 : $BUILTIN suspend 24 : $DEPENDS_ON JOB_CONTROL 25 : $FUNCTION suspend_builtin 26 : $SHORT_DOC suspend [-f] 27 : Suspend shell execution. 28 : 29 : Suspend the execution of this shell until it receives a SIGCONT signal. 30 : Unless forced, login shells cannot be suspended. 31 : 32 : Options: 33 : -f force the suspend, even if the shell is a login shell 34 : 35 : Exit Status: 36 : Returns success unless job control is not enabled or an error occurs. 37 : $END 38 : 39 : #include <config.h> 40 : 41 : #if defined (JOB_CONTROL) 42 : #if defined (HAVE_UNISTD_H) 43 : # ifdef _MINIX 44 : # include <sys/types.h> 45 : # endif 46 : # include <unistd.h> 47 : #endif 48 : 49 : #include "../bashtypes.h" 50 : #include <signal.h> 51 : #include "../bashintl.h" 52 : #include "../shell.h" 53 : #include "../jobs.h" 54 : #include "common.h" 55 : #include "bashgetopt.h" 56 : 57 : static sighandler suspend_continue __P((int)); 58 : 59 : static SigHandler *old_cont; 60 : #if 0 61 : static SigHandler *old_stop; 62 : #endif 63 : 64 : /* Continue handler. */ 65 : static sighandler 66 0 : suspend_continue (sig) 67 : int sig; 68 : { 69 0 : set_signal_handler (SIGCONT, old_cont); 70 : #if 0 71 : set_signal_handler (SIGSTOP, old_stop); 72 : #endif 73 0 : SIGRETURN (0); 74 : } 75 : 76 : /* Suspending the shell. If -f is the arg, then do the suspend 77 : no matter what. Otherwise, complain if a login shell. */ 78 : int 79 50 : suspend_builtin (list) 80 : WORD_LIST *list; 81 : { 82 50 : int opt, force; 83 : 84 50 : reset_internal_getopt (); 85 50 : force = 0; 86 50 : while ((opt = internal_getopt (list, "f")) != -1) 87 0 : switch (opt) 88 : { 89 0 : case 'f': 90 0 : force++; 91 0 : break; 92 0 : CASE_HELPOPT; 93 0 : default: 94 0 : builtin_usage (); 95 0 : return (EX_USAGE); 96 : } 97 : 98 50 : list = loptend; 99 : 100 50 : if (job_control == 0) 101 : { 102 50 : sh_nojobs (_("cannot suspend")); 103 50 : return (EXECUTION_FAILURE); 104 : } 105 : 106 0 : if (force == 0) 107 : { 108 0 : no_args (list); 109 : 110 0 : if (login_shell) 111 : { 112 0 : builtin_error (_("cannot suspend a login shell")); 113 0 : return (EXECUTION_FAILURE); 114 : } 115 : } 116 : 117 : /* XXX - should we put ourselves back into the original pgrp now? If so, 118 : call end_job_control() here and do the right thing in suspend_continue 119 : (that is, call restart_job_control()). */ 120 0 : old_cont = (SigHandler *)set_signal_handler (SIGCONT, suspend_continue); 121 : #if 0 122 : old_stop = (SigHandler *)set_signal_handler (SIGSTOP, SIG_DFL); 123 : #endif 124 0 : killpg (shell_pgrp, SIGSTOP); 125 0 : return (EXECUTION_SUCCESS); 126 : } 127 : 128 : #endif /* JOB_CONTROL */