]>
Commit | Line | Data |
---|---|---|
726f6388 JA |
1 | This file is fg_bg.def, from which is created fg_bg.c. |
2 | It implements the builtins "bg" and "fg" in Bash. | |
3 | ||
9cbcc93b | 4 | Copyright (C) 1987-2008 Free Software Foundation, Inc. |
726f6388 JA |
5 | |
6 | This file is part of GNU Bash, the Bourne Again SHell. | |
7 | ||
2e4498b3 CR |
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/>. | |
726f6388 JA |
20 | |
21 | $PRODUCES fg_bg.c | |
22 | ||
23 | $BUILTIN fg | |
24 | $FUNCTION fg_builtin | |
25 | $DEPENDS_ON JOB_CONTROL | |
26 | $SHORT_DOC fg [job_spec] | |
6a8fd0ed CR |
27 | Move job to the foreground. |
28 | ||
9cbcc93b CR |
29 | Place the job identified by JOB_SPEC in the foreground, making it the |
30 | current job. If JOB_SPEC is not present, the shell's notion of the | |
31 | current job is used. | |
6a8fd0ed CR |
32 | |
33 | Exit Status: | |
34 | Status of command placed in foreground, or failure if an error occurs. | |
726f6388 JA |
35 | $END |
36 | ||
ccc6cda3 JA |
37 | #include <config.h> |
38 | ||
d166f048 | 39 | #include "../bashtypes.h" |
726f6388 | 40 | #include <signal.h> |
ccc6cda3 JA |
41 | |
42 | #if defined (HAVE_UNISTD_H) | |
43 | # include <unistd.h> | |
44 | #endif | |
45 | ||
5e13499c CR |
46 | #include "../bashintl.h" |
47 | ||
726f6388 JA |
48 | #include "../shell.h" |
49 | #include "../jobs.h" | |
ccc6cda3 | 50 | #include "common.h" |
7117c2d2 | 51 | #include "bashgetopt.h" |
726f6388 JA |
52 | |
53 | #if defined (JOB_CONTROL) | |
54 | extern char *this_command_name; | |
55 | ||
f73dda09 | 56 | static int fg_bg __P((WORD_LIST *, int)); |
726f6388 JA |
57 | |
58 | /* How to bring a job into the foreground. */ | |
59 | int | |
60 | fg_builtin (list) | |
61 | WORD_LIST *list; | |
62 | { | |
ccc6cda3 JA |
63 | int fg_bit; |
64 | register WORD_LIST *t; | |
726f6388 | 65 | |
ccc6cda3 | 66 | if (job_control == 0) |
726f6388 | 67 | { |
7117c2d2 | 68 | sh_nojobs ((char *)NULL); |
726f6388 JA |
69 | return (EXECUTION_FAILURE); |
70 | } | |
71 | ||
ccc6cda3 JA |
72 | if (no_options (list)) |
73 | return (EX_USAGE); | |
7117c2d2 | 74 | list = loptend; |
ccc6cda3 | 75 | |
726f6388 JA |
76 | /* If the last arg on the line is '&', then start this job in the |
77 | background. Else, fg the job. */ | |
ccc6cda3 JA |
78 | for (t = list; t && t->next; t = t->next) |
79 | ; | |
80 | fg_bit = (t && t->word->word[0] == '&' && t->word->word[1] == '\0') == 0; | |
726f6388 JA |
81 | |
82 | return (fg_bg (list, fg_bit)); | |
83 | } | |
84 | #endif /* JOB_CONTROL */ | |
85 | ||
86 | $BUILTIN bg | |
87 | $FUNCTION bg_builtin | |
88 | $DEPENDS_ON JOB_CONTROL | |
ff247e74 | 89 | $SHORT_DOC bg [job_spec ...] |
6a8fd0ed CR |
90 | Move jobs to the background. |
91 | ||
9cbcc93b CR |
92 | Place the jobs identified by each JOB_SPEC in the background, as if they |
93 | had been started with `&'. If JOB_SPEC is not present, the shell's notion | |
94 | of the current job is used. | |
6a8fd0ed CR |
95 | |
96 | Exit Status: | |
97 | Returns success unless job control is not enabled or an error occurs. | |
726f6388 JA |
98 | $END |
99 | ||
100 | #if defined (JOB_CONTROL) | |
101 | /* How to put a job into the background. */ | |
102 | int | |
103 | bg_builtin (list) | |
104 | WORD_LIST *list; | |
105 | { | |
de3341d1 CR |
106 | int r; |
107 | ||
ccc6cda3 | 108 | if (job_control == 0) |
726f6388 | 109 | { |
7117c2d2 | 110 | sh_nojobs ((char *)NULL); |
726f6388 JA |
111 | return (EXECUTION_FAILURE); |
112 | } | |
113 | ||
ccc6cda3 JA |
114 | if (no_options (list)) |
115 | return (EX_USAGE); | |
7117c2d2 | 116 | list = loptend; |
ccc6cda3 | 117 | |
de3341d1 CR |
118 | /* This relies on the fact that fg_bg() takes a WORD_LIST *, but only acts |
119 | on the first member (if any) of that list. */ | |
ff247e74 | 120 | r = EXECUTION_SUCCESS; |
de3341d1 CR |
121 | do |
122 | { | |
ff247e74 CR |
123 | if (fg_bg (list, 0) == EXECUTION_FAILURE) |
124 | r = EXECUTION_FAILURE; | |
de3341d1 CR |
125 | if (list) |
126 | list = list->next; | |
127 | } | |
128 | while (list); | |
129 | ||
130 | return r; | |
726f6388 JA |
131 | } |
132 | ||
133 | /* How to put a job into the foreground/background. */ | |
134 | static int | |
135 | fg_bg (list, foreground) | |
136 | WORD_LIST *list; | |
137 | int foreground; | |
138 | { | |
139 | sigset_t set, oset; | |
ccc6cda3 | 140 | int job, status, old_async_pid; |
10590446 | 141 | JOB *j; |
726f6388 JA |
142 | |
143 | BLOCK_CHILD (set, oset); | |
144 | job = get_job_spec (list); | |
145 | ||
10590446 | 146 | if (INVALID_JOB (job)) |
726f6388 JA |
147 | { |
148 | if (job != DUP_JOB) | |
d3ad40de | 149 | sh_badjob (list ? list->word->word : _("current")); |
726f6388 JA |
150 | |
151 | goto failure; | |
152 | } | |
153 | ||
10590446 CR |
154 | j = get_job_by_jid (job); |
155 | /* Or if j->pgrp == shell_pgrp. */ | |
ccc6cda3 | 156 | if (IS_JOBCONTROL (job) == 0) |
726f6388 | 157 | { |
5e13499c | 158 | builtin_error (_("job %d started without job control"), job + 1); |
726f6388 JA |
159 | goto failure; |
160 | } | |
161 | ||
ccc6cda3 | 162 | if (foreground == 0) |
726f6388 JA |
163 | { |
164 | old_async_pid = last_asynchronous_pid; | |
10590446 | 165 | last_asynchronous_pid = j->pgrp; /* As per Posix.2 5.4.2 */ |
726f6388 JA |
166 | } |
167 | ||
168 | status = start_job (job, foreground); | |
169 | ||
170 | if (status >= 0) | |
171 | { | |
172 | /* win: */ | |
173 | UNBLOCK_CHILD (oset); | |
ff247e74 | 174 | return (foreground ? status : EXECUTION_SUCCESS); |
726f6388 JA |
175 | } |
176 | else | |
177 | { | |
ccc6cda3 | 178 | if (foreground == 0) |
726f6388 JA |
179 | last_asynchronous_pid = old_async_pid; |
180 | ||
181 | failure: | |
182 | UNBLOCK_CHILD (oset); | |
183 | return (EXECUTION_FAILURE); | |
184 | } | |
185 | } | |
186 | #endif /* JOB_CONTROL */ |