svn commit: trunk/busybox/shell
vda at busybox.net
vda at busybox.net
Sat Apr 21 13:42:55 UTC 2007
Author: vda
Date: 2007-04-21 06:42:52 -0700 (Sat, 21 Apr 2007)
New Revision: 18508
Log:
hush: fix more backgrounding bugs. Plenty of them remains still.
Modified:
trunk/busybox/shell/README
trunk/busybox/shell/hush.c
Changeset:
Modified: trunk/busybox/shell/README
===================================================================
--- trunk/busybox/shell/README 2007-04-21 10:01:14 UTC (rev 18507)
+++ trunk/busybox/shell/README 2007-04-21 13:42:52 UTC (rev 18508)
@@ -1,6 +1,12 @@
Various bits of what is known about busybox shells, in no particular order.
-2007-04-22
+2007-04-21
+hush: fixed non-backgrounding of "sleep 1 &" and totally broken
+"sleep 1 | sleep 2 &". Noticed a bug where successive jobs
+get numbers 1,2,3 even when job #1 has exited before job# 2 is started.
+(bash reuses #1 in this case)
+
+2007-04-21
hush: "sleep 1 | exit 3; echo $?" prints 0 because $? is substituted
_before_ pipe gets executed!! run_list_real() already has "pipe;echo"
parsed and handed to it for execution, so it sees "pipe"; "echo 0".
Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c 2007-04-21 10:01:14 UTC (rev 18507)
+++ trunk/busybox/shell/hush.c 2007-04-21 13:42:52 UTC (rev 18508)
@@ -384,6 +384,7 @@
static int parse_file_outer(FILE *f);
/* job management: */
static int checkjobs(struct pipe* fg_pipe);
+static int checkjobs_and_fg_shell(struct pipe* fg_pipe);
static void insert_bg_job(struct pipe *pi);
static void remove_bg_job(struct pipe *pi);
/* local variable support */
@@ -648,6 +649,8 @@
bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
return EXIT_FAILURE;
found:
+ // TODO: bash prints a string representation
+ // of job being foregrounded (like "sleep 1 | cat")
if (*child->argv[0] == 'f') {
/* Put the job into the foreground. */
tcsetpgrp(interactive_fd, pi->pgrp);
@@ -658,6 +661,7 @@
pi->progs[i].is_stopped = 0;
i = kill(- pi->pgrp, SIGCONT);
+ pi->stopped_progs = 0;
if (i < 0) {
if (errno == ESRCH) {
remove_bg_job(pi);
@@ -666,7 +670,8 @@
}
}
- pi->stopped_progs = 0;
+ if (*child->argv[0] == 'f')
+ return checkjobs_and_fg_shell(pi);
return EXIT_SUCCESS;
}
@@ -1350,6 +1355,18 @@
return rcode;
}
+static int checkjobs_and_fg_shell(struct pipe* fg_pipe)
+{
+ pid_t p;
+ int rcode = checkjobs(fg_pipe);
+ /* Job finished, move the shell to the foreground */
+ p = getpgid(0);
+ debug_printf("fg'ing ourself: getpgid(0)=%d\n", (int)p);
+ if (tcsetpgrp(interactive_fd, p) && errno != ENOTTY)
+ bb_perror_msg("tcsetpgrp-4a");
+ return rcode;
+}
+
/* run_pipe_real() starts all the jobs, but doesn't wait for anything
* to finish. See checkjobs().
*
@@ -1377,6 +1394,7 @@
/* it is not always needed, but we aim to smaller code */
int squirrel[] = { -1, -1, -1 };
int rcode;
+ const int single_fg = (pi->num_progs == 1 && pi->followup != PIPE_BG);
nextin = 0;
pi->pgrp = -1;
@@ -1386,7 +1404,7 @@
* pseudo_exec. "echo foo | read bar" doesn't work on bash, either.
*/
child = &(pi->progs[0]);
- if (pi->num_progs == 1 && child->group && child->subshell == 0) {
+ if (single_fg && child->group && child->subshell == 0) {
debug_printf("non-subshell grouping\n");
setup_redirects(child, squirrel);
/* XXX could we merge code with following builtin case,
@@ -1396,7 +1414,7 @@
return rcode;
}
- if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
+ if (single_fg && pi->progs[0].argv != NULL) {
for (i = 0; is_assignment(child->argv[i]); i++)
continue;
if (i != 0 && child->argv[i] == NULL) {
@@ -1675,13 +1693,7 @@
rcode = EXIT_SUCCESS;
} else {
if (interactive_fd) {
- pid_t p;
- rcode = checkjobs(pi);
- /* move the shell to the foreground */
- p = getpgid(0);
- if (tcsetpgrp(interactive_fd, p) && errno != ENOTTY)
- bb_perror_msg("tcsetpgrp-4");
- debug_printf("getpgid(0)=%d\n", (int)p);
+ rcode = checkjobs_and_fg_shell(pi);
} else {
rcode = checkjobs(pi);
}
More information about the busybox-cvs
mailing list