aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-08-23 22:10:04 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-08-23 22:10:04 +0200
commita12af2d9f384c7c80dbe419dceab666d53f4642d (patch)
treec759b773d2f5039baed40fc233b63099386deefb /shell
parentbd73f1d85ac180ff30d5198d37d49b33033e44a8 (diff)
downloadbusybox-a12af2d9f384c7c80dbe419dceab666d53f4642d.tar.gz
ash: make "jobs -l" more similar to bash. By Earl Chew. Fixes bug 481
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 077f5e5fc..1ec6c96c3 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -3240,9 +3240,9 @@ unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
#define FORK_NOJOB 2
/* mode flags for showjob(s) */
-#define SHOW_PGID 0x01 /* only show pgid - for jobs -p */
-#define SHOW_PID 0x04 /* include process pid */
-#define SHOW_CHANGED 0x08 /* only jobs whose state has changed */
+#define SHOW_ONLY_PGID 0x01 /* show only pgid (jobs -p) */
+#define SHOW_PIDS 0x02 /* show individual pids, not just one line per job */
+#define SHOW_CHANGED 0x04 /* only jobs whose state has changed */
/*
* A job structure contains information about a job. A job is either a
@@ -3250,7 +3250,6 @@ unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
* latter case, pidlist will be non-NULL, and will point to a -1 terminated
* array of pids.
*/
-
struct procstat {
pid_t pid; /* process id */
int status; /* last process status from wait() */
@@ -3935,7 +3934,7 @@ showjob(FILE *out, struct job *jp, int mode)
ps = jp->ps;
- if (mode & SHOW_PGID) {
+ if (mode & SHOW_ONLY_PGID) { /* jobs -p */
/* just output process (group) id of pipeline */
fprintf(out, "%d\n", ps->pid);
return;
@@ -3945,11 +3944,11 @@ showjob(FILE *out, struct job *jp, int mode)
indent_col = col;
if (jp == curjob)
- s[col - 2] = '+';
+ s[col - 3] = '+';
else if (curjob && jp == curjob->prev_job)
- s[col - 2] = '-';
+ s[col - 3] = '-';
- if (mode & SHOW_PID)
+ if (mode & SHOW_PIDS)
col += fmtstr(s + col, 16, "%d ", ps->pid);
psend = ps + jp->nprocs;
@@ -3963,25 +3962,32 @@ showjob(FILE *out, struct job *jp, int mode)
status = jp->stopstatus;
col += sprint_status(s + col, status, 0);
}
+ /* By now, "[JOBID]* [maybe PID] STATUS" is printed */
+ /* This loop either prints "<cmd1> | <cmd2> | <cmd3>" line
+ * or prints several "PID | <cmdN>" lines,
+ * depending on SHOW_PIDS bit.
+ * We do not print status of individual processes
+ * between PID and <cmdN>. bash does it, but not very well:
+ * first line shows overall job status, not process status,
+ * making it impossible to know 1st process status.
+ */
goto start;
-
- do {
+ while (1) {
/* for each process */
- col = fmtstr(s, 48, " |\n%*c%d ", indent_col, ' ', ps->pid) - 3;
+ s[0] = '\0';
+ col = 33;
+ if (mode & SHOW_PIDS)
+ col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->pid) - 1;
start:
- fprintf(out, "%s%*c%s",
- s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd
- );
- if (!(mode & SHOW_PID)) {
- showpipe(jp, out);
+ fprintf(out, "%s%*c", s, 33 - col >= 0 ? 33 - col : 0, ' ');
+ if (ps != jp->ps)
+ fprintf(out, "| ");
+ fprintf(out, "%s", ps->cmd);
+ if (++ps == psend)
break;
- }
- if (++ps == psend) {
- outcslow('\n', out);
- break;
- }
- } while (1);
+ }
+ outcslow('\n', out);
jp->changed = 0;
@@ -4021,15 +4027,15 @@ jobscmd(int argc UNUSED_PARAM, char **argv)
mode = 0;
while ((m = nextopt("lp"))) {
if (m == 'l')
- mode = SHOW_PID;
+ mode |= SHOW_PIDS;
else
- mode = SHOW_PGID;
+ mode |= SHOW_ONLY_PGID;
}
argv = argptr;
if (*argv) {
do
- showjob(stdout, getjob(*argv,0), mode);
+ showjob(stdout, getjob(*argv, 0), mode);
while (*++argv);
} else
showjobs(stdout, mode);