aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorTim J. Robbins <tjr@FreeBSD.org>2002-05-31 14:04:23 +0000
committerTim J. Robbins <tjr@FreeBSD.org>2002-05-31 14:04:23 +0000
commitad8a0759025a097be0dd6ebeae3e2c57837e7ebf (patch)
tree8c0ae8c6b41224d3a4d8ce7115141f17cc2c12af /bin
parentdc1024256cc021c17c086fa406121e02f986b4c7 (diff)
downloadsrc-ad8a0759025a097be0dd6ebeae3e2c57837e7ebf.tar.gz
src-ad8a0759025a097be0dd6ebeae3e2c57837e7ebf.zip
Add -s (output PID's only) and -l (show PID's) options to the jobs(1)
builtin. Modify the output format to match what SUSv3 requires.
Notes
Notes: svn path=/head/; revision=97669
Diffstat (limited to 'bin')
-rw-r--r--bin/sh/jobs.c80
-rw-r--r--bin/sh/jobs.h2
-rw-r--r--bin/sh/main.c2
-rw-r--r--bin/sh/sh.119
4 files changed, 85 insertions, 18 deletions
diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c
index fc92e65824c6..822500ba4090 100644
--- a/bin/sh/jobs.c
+++ b/bin/sh/jobs.c
@@ -109,7 +109,7 @@ STATIC void setcurjob(struct job *);
STATIC void deljob(struct job *);
STATIC struct job *getcurjob(struct job *);
#endif
-STATIC void showjob(struct job *);
+STATIC void showjob(struct job *, int, int);
/*
@@ -271,31 +271,85 @@ restartjob(struct job *jp)
int
-jobscmd(int argc __unused, char **argv __unused)
+jobscmd(int argc, char *argv[])
{
- showjobs(0);
- return 0;
+ struct job *jp;
+ char *id;
+ int ch, sformat, lformat;
+
+ optind = optreset = 1;
+ sformat = lformat = 0;
+ while ((ch = getopt(argc, argv, "ls")) != -1) {
+ switch (ch) {
+ case 'l':
+ lformat = 1;
+ break;
+ case 's':
+ sformat = 1;
+ break;
+ case '?':
+ default:
+ error("unknown option: -%c", optopt);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0)
+ showjobs(0, sformat, lformat);
+ else
+ while ((id = *argv++) != NULL)
+ showjob(getjob(id), sformat, lformat);
+
+ return (0);
}
STATIC void
-showjob(struct job *jp)
+showjob(struct job *jp, int sformat, int lformat)
{
char s[64];
struct procstat *ps;
- int col, i, jobno, procno;
+ struct job *j;
+ int col, curr, i, jobno, prev, procno;
+ char c;
procno = jp->nprocs;
jobno = jp - jobtab + 1;
+ curr = prev = 0;
+#if JOBS
+ if ((j = getcurjob(NULL)) != NULL) {
+ curr = j - jobtab + 1;
+ if ((j = getcurjob(j)) != NULL)
+ prev = j - jobtab + 1;
+ }
+#endif
for (ps = jp->ps ; ; ps++) { /* for each process */
+ if (sformat) {
+ out1fmt("%d\n", ps->pid);
+ goto skip;
+ }
+ if (!lformat && ps != jp->ps)
+ goto skip;
+ if (jobno == curr)
+ c = '+';
+ else if (jobno == prev)
+ c = '-';
+ else
+ c = ' ';
if (ps == jp->ps)
- fmtstr(s, 64, "[%d] %d ", jobno, ps->pid);
+ fmtstr(s, 64, "[%d] %c ", jobno, c);
else
- fmtstr(s, 64, " %d ", ps->pid);
+ fmtstr(s, 64, " %c ", c);
out1str(s);
col = strlen(s);
+ if (lformat) {
+ fmtstr(s, 64, "%d ", ps->pid);
+ out1str(s);
+ col += strlen(s);
+ }
s[0] = '\0';
if (ps->status == -1) {
- /* don't print anything */
+ strcpy(s, "Running");
} else if (WIFEXITED(ps->status)) {
fmtstr(s, 64, "Exit %d", WEXITSTATUS(ps->status));
} else {
@@ -320,7 +374,7 @@ showjob(struct job *jp)
} while (col < 30);
out1str(ps->cmd);
out1c('\n');
- if (--procno <= 0)
+skip: if (--procno <= 0)
break;
}
}
@@ -335,7 +389,7 @@ showjob(struct job *jp)
*/
void
-showjobs(int change)
+showjobs(int change, int sformat, int lformat)
{
int jobno;
struct job *jp;
@@ -351,7 +405,7 @@ showjobs(int change)
}
if (change && ! jp->changed)
continue;
- showjob(jp);
+ showjob(jp, sformat, lformat);
jp->changed = 0;
if (jp->state == JOBDONE) {
freejob(jp);
@@ -909,7 +963,7 @@ dowait(int block, struct job *job)
sig = WTERMSIG(status);
}
if (sig != 0 && sig != SIGINT && sig != SIGPIPE)
- showjob(thisjob);
+ showjob(thisjob, 0, 0);
} else {
TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job));
if (thisjob)
diff --git a/bin/sh/jobs.h b/bin/sh/jobs.h
index 2dba4e1ac6a0..ad0a74f33317 100644
--- a/bin/sh/jobs.h
+++ b/bin/sh/jobs.h
@@ -87,7 +87,7 @@ void setjobctl(int);
int fgcmd(int, char **);
int bgcmd(int, char **);
int jobscmd(int, char **);
-void showjobs(int);
+void showjobs(int, int, int);
int waitcmd(int, char **);
int jobidcmd(int, char **);
struct job *makejob(union node *, int);
diff --git a/bin/sh/main.c b/bin/sh/main.c
index 595c212dc8cb..460693a1f76d 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -229,7 +229,7 @@ cmdloop(int top)
inter = 0;
if (iflag && top) {
inter++;
- showjobs(1);
+ showjobs(1, 0, 0);
chkmail(0);
flushout(&output);
}
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index eb3712b05916..b1bd6ff93b7f 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -1570,9 +1570,22 @@ Print the process id's of the processes in the specified
If the
.Ar job
argument is omitted, use the current job.
-.It Ic jobs
-This command lists out all the background processes
-which are children of the current shell process.
+.It Xo
+.Ic jobs
+.Op Fl ls
+.Op Ar job ...
+.Xc
+Print information about the specified jobs, or all jobs if no
+.Ar job
+argument is given.
+The information printed includes job ID, status and command name.
+.Pp
+If the
+.Fl l
+option is specified, the PID of each job is also printed.
+If the
+.Fl s
+option is specified, only the PID's of the jobs are printed, one per line.
.It Ic pwd Op Fl LP
Print the path of the current directory. The builtin command may
differ from the program of the same name because the