diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-14 11:16:29 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-14 11:16:29 +0000 |
commit | 8a28e620ce6017fd184c26a7ce25f5e167a90fe7 (patch) | |
tree | b1c51ade423d7670655c8e2d02acbae4d58276c9 | |
parent | bf3561fd15cff3fbfe6f67d134c23149ed35f493 (diff) | |
download | busybox-w32-8a28e620ce6017fd184c26a7ce25f5e167a90fe7.tar.gz busybox-w32-8a28e620ce6017fd184c26a7ce25f5e167a90fe7.tar.bz2 busybox-w32-8a28e620ce6017fd184c26a7ce25f5e167a90fe7.zip |
lash: recognize and use NOFORK applets
lash,hush: fix kill buglet (didn't properly recognize ESRCH)
-rw-r--r-- | shell/hush.c | 37 | ||||
-rw-r--r-- | shell/lash.c | 53 |
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) | |||
547 | static int builtin_fg_bg(struct child_prog *child) | 547 | static 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) | |||
257 | static int builtin_fg_bg(struct child_prog *child) | 257 | static 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 |