aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-04-14 11:16:29 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-04-14 11:16:29 +0000
commit9410d71db68f2c5a1ec9fa339fbf95949525459e (patch)
treeb1c51ade423d7670655c8e2d02acbae4d58276c9
parentf906ba0b5515f9075b704eb11487f9175e0abf0f (diff)
downloadbusybox-w32-9410d71db68f2c5a1ec9fa339fbf95949525459e.tar.gz
busybox-w32-9410d71db68f2c5a1ec9fa339fbf95949525459e.tar.bz2
busybox-w32-9410d71db68f2c5a1ec9fa339fbf95949525459e.zip
lash: recognize and use NOFORK applets
lash,hush: fix kill buglet (didn't properly recognize ESRCH) git-svn-id: svn://busybox.net/trunk/busybox@18438 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--shell/hush.c37
-rw-r--r--shell/lash.c53
2 files changed, 46 insertions, 44 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 9362e5916..0b5e2a5de 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -547,7 +547,7 @@ static int builtin_export(struct child_prog *child)
547static int builtin_fg_bg(struct child_prog *child) 547static int builtin_fg_bg(struct child_prog *child)
548{ 548{
549 int i, jobnum; 549 int i, jobnum;
550 struct pipe *pi = NULL; 550 struct pipe *pi;
551 551
552 if (!interactive) 552 if (!interactive)
553 return EXIT_FAILURE; 553 return EXIT_FAILURE;
@@ -555,29 +555,24 @@ static int builtin_fg_bg(struct child_prog *child)
555 if (!child->argv[1]) { 555 if (!child->argv[1]) {
556 for (pi = job_list; pi; pi = pi->next) { 556 for (pi = job_list; pi; pi = pi->next) {
557 if (pi->jobid == last_jobid) { 557 if (pi->jobid == last_jobid) {
558 break; 558 goto found;
559 }
560 }
561 if (!pi) {
562 bb_error_msg("%s: no current job", child->argv[0]);
563 return EXIT_FAILURE;
564 }
565 } else {
566 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
567 bb_error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]);
568 return EXIT_FAILURE;
569 }
570 for (pi = job_list; pi; pi = pi->next) {
571 if (pi->jobid == jobnum) {
572 break;
573 } 559 }
574 } 560 }
575 if (!pi) { 561 bb_error_msg("%s: no current job", child->argv[0]);
576 bb_error_msg("%s: %d: no such job", child->argv[0], jobnum); 562 return EXIT_FAILURE;
577 return EXIT_FAILURE; 563 }
564 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
565 bb_error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]);
566 return EXIT_FAILURE;
567 }
568 for (pi = job_list; pi; pi = pi->next) {
569 if (pi->jobid == jobnum) {
570 goto found;
578 } 571 }
579 } 572 }
580 573 bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
574 return EXIT_FAILURE;
575 found:
581 if (*child->argv[0] == 'f') { 576 if (*child->argv[0] == 'f') {
582 /* Put the job into the foreground. */ 577 /* Put the job into the foreground. */
583 tcsetpgrp(shell_terminal, pi->pgrp); 578 tcsetpgrp(shell_terminal, pi->pgrp);
@@ -589,7 +584,7 @@ static int builtin_fg_bg(struct child_prog *child)
589 584
590 i = kill(- pi->pgrp, SIGCONT); 585 i = kill(- pi->pgrp, SIGCONT);
591 if (i < 0) { 586 if (i < 0) {
592 if (i == ESRCH) { 587 if (errno == ESRCH) {
593 remove_bg_job(pi); 588 remove_bg_job(pi);
594 } else { 589 } else {
595 bb_perror_msg("kill (SIGCONT)"); 590 bb_perror_msg("kill (SIGCONT)");
diff --git a/shell/lash.c b/shell/lash.c
index 6fe2ddc76..24e48c337 100644
--- a/shell/lash.c
+++ b/shell/lash.c
@@ -257,35 +257,30 @@ static int builtin_exit(struct child_prog *child)
257static int builtin_fg_bg(struct child_prog *child) 257static int builtin_fg_bg(struct child_prog *child)
258{ 258{
259 int i, jobnum; 259 int i, jobnum;
260 struct job *job = NULL; 260 struct job *job;
261 261
262 /* If they gave us no args, assume they want the last backgrounded task */ 262 /* If they gave us no args, assume they want the last backgrounded task */
263 if (!child->argv[1]) { 263 if (!child->argv[1]) {
264 for (job = child->family->job_list->head; job; job = job->next) { 264 for (job = child->family->job_list->head; job; job = job->next) {
265 if (job->jobid == last_jobid) { 265 if (job->jobid == last_jobid) {
266 break; 266 goto found;
267 } 267 }
268 } 268 }
269 if (!job) { 269 bb_error_msg("%s: no current job", child->argv[0]);
270 bb_error_msg("%s: no current job", child->argv[0]); 270 return EXIT_FAILURE;
271 return EXIT_FAILURE; 271 }
272 } 272 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
273 } else { 273 bb_error_msg(bb_msg_invalid_arg, child->argv[1], child->argv[0]);
274 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) { 274 return EXIT_FAILURE;
275 bb_error_msg(bb_msg_invalid_arg, child->argv[1], child->argv[0]); 275 }
276 return EXIT_FAILURE; 276 for (job = child->family->job_list->head; job; job = job->next) {
277 } 277 if (job->jobid == jobnum) {
278 for (job = child->family->job_list->head; job; job = job->next) { 278 goto found;
279 if (job->jobid == jobnum) {
280 break;
281 }
282 }
283 if (!job) {
284 bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
285 return EXIT_FAILURE;
286 } 279 }
287 } 280 }
288 281 bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
282 return EXIT_FAILURE;
283 found:
289 if (*child->argv[0] == 'f') { 284 if (*child->argv[0] == 'f') {
290 /* Put the job into the foreground. */ 285 /* Put the job into the foreground. */
291 tcsetpgrp(shell_terminal, job->pgrp); 286 tcsetpgrp(shell_terminal, job->pgrp);
@@ -301,7 +296,7 @@ static int builtin_fg_bg(struct child_prog *child)
301 296
302 i = kill(- job->pgrp, SIGCONT); 297 i = kill(- job->pgrp, SIGCONT);
303 if (i < 0) { 298 if (i < 0) {
304 if (i == ESRCH) { 299 if (errno == ESRCH) {
305 remove_job(&job_list, job); 300 remove_job(&job_list, job);
306 } else { 301 } else {
307 bb_perror_msg("kill (SIGCONT)"); 302 bb_perror_msg("kill (SIGCONT)");
@@ -1241,6 +1236,9 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
1241 * is doomed to failure, and doesn't work on bash, either. 1236 * is doomed to failure, and doesn't work on bash, either.
1242 */ 1237 */
1243 if (newjob->num_progs == 1) { 1238 if (newjob->num_progs == 1) {
1239 int rcode;
1240 int squirrel[] = {-1, -1, -1};
1241
1244 /* Check if the command sets an environment variable. */ 1242 /* Check if the command sets an environment variable. */
1245 if (strchr(child->argv[0], '=') != NULL) { 1243 if (strchr(child->argv[0], '=') != NULL) {
1246 child->argv[1] = child->argv[0]; 1244 child->argv[1] = child->argv[0];
@@ -1249,14 +1247,23 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
1249 1247
1250 for (x = bltins; x <= &VEC_LAST(bltins); x++) { 1248 for (x = bltins; x <= &VEC_LAST(bltins); x++) {
1251 if (strcmp(child->argv[0], x->cmd) == 0) { 1249 if (strcmp(child->argv[0], x->cmd) == 0) {
1252 int rcode;
1253 int squirrel[] = {-1, -1, -1};
1254 setup_redirects(child, squirrel); 1250 setup_redirects(child, squirrel);
1255 rcode = x->function(child); 1251 rcode = x->function(child);
1256 restore_redirects(squirrel); 1252 restore_redirects(squirrel);
1257 return rcode; 1253 return rcode;
1258 } 1254 }
1259 } 1255 }
1256#if ENABLE_FEATURE_SH_STANDALONE
1257 {
1258 const struct bb_applet *a = find_applet_by_name(child->argv[i]);
1259 if (a && a->nofork) {
1260 setup_redirects(child, squirrel);
1261 rcode = run_nofork_applet(a, child->argv + i);
1262 restore_redirects(squirrel);
1263 return rcode;
1264 }
1265 }
1266#endif
1260 } 1267 }
1261 1268
1262#if BB_MMU 1269#if BB_MMU