1 This file is jobs.def
, from which is created jobs.c.
2 It implements the builtins
"jobs" and
"disown" in Bush.
4 Copyright (C
) 1987-2020 Free Software Foundation
, Inc.
6 This file is part of GNU Bush
, the Bourne Again SHell.
8 Bush 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 Bush 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 Bush. 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 lists 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 "../src/bushtypes.h"
54 #if defined (HAVE_UNISTD_H)
58 #include "../src/bushansi.h"
59 #include "../src/bushintl.h"
61 #include "../src/shell.h"
62 #include "../src/jobs.h"
63 #include "../src/runner/execute_cmd.h"
64 #include "bushgetopt.h"
67 #define JSTATE_ANY 0x0
68 #define JSTATE_RUNNING 0x1
69 #define JSTATE_STOPPED 0x2
71 static int execute_list_with_replacements PARAMS((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;
131 return (execute_list_with_replacements (list));
138 list_all_jobs (form);
141 list_running_jobs (form);
144 list_stopped_jobs (form);
147 return (EXECUTION_SUCCESS);
152 BLOCK_CHILD (set, oset);
153 job = get_job_spec (list);
155 if ((job == NO_JOB) || jobs == 0 || get_job_by_jid (job) == 0)
157 sh_badjob (list->word->word);
160 else if (job != DUP_JOB)
161 list_one_job ((JOB *)NULL, form, 0, job);
163 UNBLOCK_CHILD (oset);
166 return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
170 execute_list_with_replacements (list)
173 register WORD_LIST *l;
178 /* First do the replacement of job specifications with pids. */
179 for (l = list; l; l = l->next)
181 if (l->word->word[0] == '%') /* we have a winner */
183 job = get_job_spec (l);
185 /* A bad job spec is not really a job spec! Pass it through. */
186 if (INVALID_JOB (job))
189 j = get_job_by_jid (job);
190 free (l->word->word);
191 l->word->word = itos (j->pgrp);
195 /* Next make a new simple command and execute it. */
196 begin_unwind_frame ("jobs_builtin
");
198 command = make_bare_simple_command ();
199 command->value.Simple->words = copy_word_list (list);
200 command->value.Simple->redirects = (REDIRECT *)NULL;
201 command->flags |= CMD_INHIBIT_EXPANSION;
202 command->value.Simple->flags |= CMD_INHIBIT_EXPANSION;
204 add_unwind_protect (dispose_command, command);
205 result = execute_command (command);
206 dispose_command (command);
208 discard_unwind_frame ("jobs_builtin
");
211 #endif /* JOB_CONTROL */
214 $FUNCTION disown_builtin
215 $DEPENDS_ON JOB_CONTROL
216 $SHORT_DOC disown [-h] [-ar] [jobspec ... | pid ...]
217 Remove jobs from current shell.
219 Removes each JOBSPEC argument from the table of active jobs. Without
220 any JOBSPECs, the shell uses its notion of the current job.
223 -a remove all jobs if JOBSPEC is not supplied
224 -h mark each JOBSPEC so that SIGHUP is not sent to the job if the
225 shell receives a SIGHUP
226 -r remove only running jobs
229 Returns success unless an invalid option or JOBSPEC is given.
232 #if defined (JOB_CONTROL)
234 disown_builtin (list)
237 int opt, job, retval, nohup_only, running_jobs, all_jobs;
241 nohup_only = running_jobs = all_jobs = 0;
242 reset_internal_getopt ();
243 while ((opt = internal_getopt (list, "ahr
")) != -1)
263 retval = EXECUTION_SUCCESS;
265 /* `disown -a' or `disown -r' */
266 if (list == 0 && (all_jobs || running_jobs))
269 nohup_all_jobs (running_jobs);
271 delete_all_jobs (running_jobs);
272 return (EXECUTION_SUCCESS);
277 BLOCK_CHILD (set, oset);
278 job = (list && legal_number (list->word->word, &pid_value) && pid_value == (pid_t) pid_value)
279 ? get_job_by_pid ((pid_t) pid_value, 0, 0)
280 : get_job_spec (list);
282 if (job == NO_JOB || jobs == 0 || INVALID_JOB (job))
284 sh_badjob (list ? list->word->word : _("current
"));
285 retval = EXECUTION_FAILURE;
291 UNBLOCK_CHILD (oset);
300 #endif /* JOB_CONTROL */