1 This file is jobs.def, from which is created jobs.c.
2 It implements the builtins "jobs" and "disown" in Bash.
4 Copyright (C) 1987-2009 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
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.
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.
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/>.
24 $FUNCTION jobs_builtin
25 $DEPENDS_ON JOB_CONTROL
26 $SHORT_DOC jobs [-lnprs] [jobspec ...] or jobs -x command [args]
27 Display status of jobs.
29 Lists the active jobs. JOBSPEC restricts output to that job.
30 Without options, the status of all active jobs is displayed.
33 -l lists process IDs in addition to the normal information
34 -n list only processes that have changed status since the last
36 -p lists process IDs only
37 -r restrict output to running jobs
38 -s restrict output to stopped jobs
40 If -x is supplied, COMMAND is run after all job specifications that
41 appear in ARGS have been replaced with the process ID of that job's
45 Returns success unless an invalid option is given or an error occurs.
46 If -x is used, returns the exit status of COMMAND.
51 #if defined (JOB_CONTROL)
52 #include "../bashtypes.h"
54 #if defined (HAVE_UNISTD_H)
58 #include "../bashansi.h"
59 #include "../bashintl.h"
63 #include "../execute_cmd.h"
64 #include "bashgetopt.h"
67 #define JSTATE_ANY 0x0
68 #define JSTATE_RUNNING 0x1
69 #define JSTATE_STOPPED 0x2
71 static int execute_list_with_replacements __P((WORD_LIST *));
73 /* The `jobs' command. Prints outs a list of active jobs. If the
74 argument `-l' is given, then the process id's are printed also.
75 If the argument `-p' is given, print the process group leader's
76 pid only. If `-n' is given, only processes that have changed
77 status since the last notification are printed. If -x is given,
78 replace all job specs with the pid of the appropriate process
79 group leader and execute the command. The -r and -s options mean
80 to print info about running and stopped jobs only, respectively. */
85 int form, execute, state, opt, any_failed, job;
88 execute = any_failed = 0;
89 form = JLIST_STANDARD;
92 reset_internal_getopt ();
93 while ((opt = internal_getopt (list, "lpnxrs")) != -1)
101 form = JLIST_PID_ONLY;
104 form = JLIST_CHANGED_ONLY;
107 if (form != JLIST_STANDARD)
109 builtin_error (_("no other options allowed with `-x'"));
110 return (EXECUTION_FAILURE);
115 state = JSTATE_RUNNING;
118 state = JSTATE_STOPPED;
130 return (execute_list_with_replacements (list));
137 list_all_jobs (form);
140 list_running_jobs (form);
143 list_stopped_jobs (form);
146 return (EXECUTION_SUCCESS);
151 BLOCK_CHILD (set, oset);
152 job = get_job_spec (list);
154 if ((job == NO_JOB) || jobs == 0 || get_job_by_jid (job) == 0)
156 sh_badjob (list->word->word);
159 else if (job != DUP_JOB)
160 list_one_job ((JOB *)NULL, form, 0, job);
162 UNBLOCK_CHILD (oset);
165 return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
169 execute_list_with_replacements (list)
172 register WORD_LIST *l;
177 /* First do the replacement of job specifications with pids. */
178 for (l = list; l; l = l->next)
180 if (l->word->word[0] == '%') /* we have a winner */
182 job = get_job_spec (l);
184 /* A bad job spec is not really a job spec! Pass it through. */
185 if (INVALID_JOB (job))
188 j = get_job_by_jid (job);
189 free (l->word->word);
190 l->word->word = itos (j->pgrp);
194 /* Next make a new simple command and execute it. */
195 begin_unwind_frame ("jobs_builtin");
197 command = make_bare_simple_command ();
198 command->value.Simple->words = copy_word_list (list);
199 command->value.Simple->redirects = (REDIRECT *)NULL;
200 command->flags |= CMD_INHIBIT_EXPANSION;
201 command->value.Simple->flags |= CMD_INHIBIT_EXPANSION;
203 add_unwind_protect (dispose_command, command);
204 result = execute_command (command);
205 dispose_command (command);
207 discard_unwind_frame ("jobs_builtin");
210 #endif /* JOB_CONTROL */
213 $FUNCTION disown_builtin
214 $DEPENDS_ON JOB_CONTROL
215 $SHORT_DOC disown [-h] [-ar] [jobspec ...]
216 Remove jobs from current shell.
218 Removes each JOBSPEC argument from the table of active jobs. Without
219 any JOBSPECs, the shell uses its notion of the current job.
222 -a remove all jobs if JOBSPEC is not supplied
223 -h mark each JOBSPEC so that SIGHUP is not sent to the job if the
224 shell receives a SIGHUP
225 -r remove only running jobs
228 Returns success unless an invalid option or JOBSPEC is given.
231 #if defined (JOB_CONTROL)
233 disown_builtin (list)
236 int opt, job, retval, nohup_only, running_jobs, all_jobs;
240 nohup_only = running_jobs = all_jobs = 0;
241 reset_internal_getopt ();
242 while ((opt = internal_getopt (list, "ahr")) != -1)
261 retval = EXECUTION_SUCCESS;
263 /* `disown -a' or `disown -r' */
264 if (list == 0 && (all_jobs || running_jobs))
267 nohup_all_jobs (running_jobs);
269 delete_all_jobs (running_jobs);
270 return (EXECUTION_SUCCESS);
275 BLOCK_CHILD (set, oset);
276 job = (list && legal_number (list->word->word, &pid_value) && pid_value == (pid_t) pid_value)
277 ? get_job_by_pid ((pid_t) pid_value, 0)
278 : get_job_spec (list);
280 if (job == NO_JOB || jobs == 0 || INVALID_JOB (job))
282 sh_badjob (list ? list->word->word : _("current"));
283 retval = EXECUTION_FAILURE;
289 UNBLOCK_CHILD (oset);
298 #endif /* JOB_CONTROL */