aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-14 11:16:29 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-14 11:16:29 +0000
commit8a28e620ce6017fd184c26a7ce25f5e167a90fe7 (patch)
treeb1c51ade423d7670655c8e2d02acbae4d58276c9
parentbf3561fd15cff3fbfe6f67d134c23149ed35f493 (diff)
downloadbusybox-8a28e620ce6017fd184c26a7ce25f5e167a90fe7.tar.gz
lash: recognize and use NOFORK applets
lash,hush: fix kill buglet (didn't properly recognize ESRCH)
-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)
static int builtin_fg_bg(struct child_prog *child)
{
int i, jobnum;
- struct pipe *pi = NULL;
+ struct pipe *pi;
if (!interactive)
return EXIT_FAILURE;
@@ -555,29 +555,24 @@ static int builtin_fg_bg(struct child_prog *child)
if (!child->argv[1]) {
for (pi = job_list; pi; pi = pi->next) {
if (pi->jobid == last_jobid) {
- break;
- }
- }
- if (!pi) {
- bb_error_msg("%s: no current job", child->argv[0]);
- return EXIT_FAILURE;
- }
- } else {
- if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
- bb_error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]);
- return EXIT_FAILURE;
- }
- for (pi = job_list; pi; pi = pi->next) {
- if (pi->jobid == jobnum) {
- break;
+ goto found;
}
}
- if (!pi) {
- bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
- return EXIT_FAILURE;
+ bb_error_msg("%s: no current job", child->argv[0]);
+ return EXIT_FAILURE;
+ }
+ if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
+ bb_error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]);
+ return EXIT_FAILURE;
+ }
+ for (pi = job_list; pi; pi = pi->next) {
+ if (pi->jobid == jobnum) {
+ goto found;
}
}
-
+ bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
+ return EXIT_FAILURE;
+ found:
if (*child->argv[0] == 'f') {
/* Put the job into the foreground. */
tcsetpgrp(shell_terminal, pi->pgrp);
@@ -589,7 +584,7 @@ static int builtin_fg_bg(struct child_prog *child)
i = kill(- pi->pgrp, SIGCONT);
if (i < 0) {
- if (i == ESRCH) {
+ if (errno == ESRCH) {
remove_bg_job(pi);
} else {
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)
static int builtin_fg_bg(struct child_prog *child)
{
int i, jobnum;
- struct job *job = NULL;
+ struct job *job;
/* If they gave us no args, assume they want the last backgrounded task */
if (!child->argv[1]) {
for (job = child->family->job_list->head; job; job = job->next) {
if (job->jobid == last_jobid) {
- break;
+ goto found;
}
}
- if (!job) {
- bb_error_msg("%s: no current job", child->argv[0]);
- return EXIT_FAILURE;
- }
- } else {
- if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
- bb_error_msg(bb_msg_invalid_arg, child->argv[1], child->argv[0]);
- return EXIT_FAILURE;
- }
- for (job = child->family->job_list->head; job; job = job->next) {
- if (job->jobid == jobnum) {
- break;
- }
- }
- if (!job) {
- bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
- return EXIT_FAILURE;
+ bb_error_msg("%s: no current job", child->argv[0]);
+ return EXIT_FAILURE;
+ }
+ if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
+ bb_error_msg(bb_msg_invalid_arg, child->argv[1], child->argv[0]);
+ return EXIT_FAILURE;
+ }
+ for (job = child->family->job_list->head; job; job = job->next) {
+ if (job->jobid == jobnum) {
+ goto found;
}
}
-
+ bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
+ return EXIT_FAILURE;
+ found:
if (*child->argv[0] == 'f') {
/* Put the job into the foreground. */
tcsetpgrp(shell_terminal, job->pgrp);
@@ -301,7 +296,7 @@ static int builtin_fg_bg(struct child_prog *child)
i = kill(- job->pgrp, SIGCONT);
if (i < 0) {
- if (i == ESRCH) {
+ if (errno == ESRCH) {
remove_job(&job_list, job);
} else {
bb_perror_msg("kill (SIGCONT)");
@@ -1241,6 +1236,9 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
* is doomed to failure, and doesn't work on bash, either.
*/
if (newjob->num_progs == 1) {
+ int rcode;
+ int squirrel[] = {-1, -1, -1};
+
/* Check if the command sets an environment variable. */
if (strchr(child->argv[0], '=') != NULL) {
child->argv[1] = child->argv[0];
@@ -1249,14 +1247,23 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
for (x = bltins; x <= &VEC_LAST(bltins); x++) {
if (strcmp(child->argv[0], x->cmd) == 0) {
- int rcode;
- int squirrel[] = {-1, -1, -1};
setup_redirects(child, squirrel);
rcode = x->function(child);
restore_redirects(squirrel);
return rcode;
}
}
+#if ENABLE_FEATURE_SH_STANDALONE
+ {
+ const struct bb_applet *a = find_applet_by_name(child->argv[i]);
+ if (a && a->nofork) {
+ setup_redirects(child, squirrel);
+ rcode = run_nofork_applet(a, child->argv + i);
+ restore_redirects(squirrel);
+ return rcode;
+ }
+ }
+#endif
}
#if BB_MMU