1This file is suspend.def, from which is created suspend.c.
2It implements the builtin "suspend" in Bash.
3
4Copyright (C) 1987-2003 Free Software Foundation, Inc.
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
8Bash is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with Bash; see the file COPYING.  If not, write to the Free Software
20Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
21
22$PRODUCES suspend.c
23
24$BUILTIN suspend
25$DEPENDS_ON JOB_CONTROL
26$FUNCTION suspend_builtin
27$SHORT_DOC suspend [-f]
28Suspend the execution of this shell until it receives a SIGCONT
29signal.  The `-f' if specified says not to complain about this
30being a login shell if it is; just suspend anyway.
31$END
32
33#include <config.h>
34
35#if defined (JOB_CONTROL)
36#if defined (HAVE_UNISTD_H)
37#  ifdef _MINIX
38#    include <sys/types.h>
39#  endif
40#  include <unistd.h>
41#endif
42
43#include "../bashtypes.h"
44#include <signal.h>
45#include "../bashintl.h"
46#include "../shell.h"
47#include "../jobs.h"
48#include "common.h"
49#include "bashgetopt.h"
50
51static sighandler suspend_continue __P((int));
52
53static SigHandler *old_cont;
54#if 0
55static SigHandler *old_stop;
56#endif
57
58/* Continue handler. */
59static sighandler
60suspend_continue (sig)
61     int sig;
62{
63  set_signal_handler (SIGCONT, old_cont);
64#if 0
65  set_signal_handler (SIGSTOP, old_stop);
66#endif
67  SIGRETURN (0);
68}
69
70/* Suspending the shell.  If -f is the arg, then do the suspend
71   no matter what.  Otherwise, complain if a login shell. */
72int
73suspend_builtin (list)
74     WORD_LIST *list;
75{
76  int opt, force;
77
78  reset_internal_getopt ();
79  force = 0;
80  while ((opt = internal_getopt (list, "f")) != -1)
81    switch (opt)
82      {
83      case 'f':
84	force++;
85	break;
86      default:
87	builtin_usage ();
88	return (EX_USAGE);
89      }
90      
91  list = loptend;
92
93  if (job_control == 0)
94    {
95      sh_nojobs (_("cannot suspend"));
96      return (EXECUTION_FAILURE);
97    }
98
99  if (force == 0)  
100    {
101      no_args (list);
102
103      if (login_shell)
104	{
105	  builtin_error (_("cannot suspend a login shell"));
106	  return (EXECUTION_FAILURE);
107	}
108    }
109
110  /* XXX - should we put ourselves back into the original pgrp now?  If so,
111     call end_job_control() here and do the right thing in suspend_continue
112     (that is, call restart_job_control()). */
113  old_cont = (SigHandler *)set_signal_handler (SIGCONT, suspend_continue);
114#if 0
115  old_stop = (SigHandler *)set_signal_handler (SIGSTOP, SIG_DFL);
116#endif
117  killpg (shell_pgrp, SIGSTOP);
118  return (EXECUTION_SUCCESS);
119}
120
121#endif /* JOB_CONTROL */
122