]> git.saurik.com Git - apple/shell_cmds.git/blobdiff - sh/jobs.c
shell_cmds-216.60.1.tar.gz
[apple/shell_cmds.git] / sh / jobs.c
index b531231e4a592f9ecd1f7db34999a912cc05300d..358153bd44695886c45d3f58fa90a54fd6955714 100644 (file)
--- a/sh/jobs.c
+++ b/sh/jobs.c
@@ -13,7 +13,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -36,7 +36,7 @@ static char sccsid[] = "@(#)jobs.c    8.5 (Berkeley) 5/4/95";
 #endif
 #endif /* not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/bin/sh/jobs.c 328818 2018-02-02 22:53:58Z jilles $");
 
 #include <sys/ioctl.h>
 #include <sys/param.h>
@@ -75,6 +75,42 @@ __FBSDID("$FreeBSD$");
 #include "builtins.h"
 
 
+/*
+ * A job structure contains information about a job.  A job is either a
+ * single process or a set of processes contained in a pipeline.  In the
+ * 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;             /* status flags (defined above) */
+       char *cmd;              /* text of command being run */
+};
+
+
+/* states */
+#define JOBSTOPPED 1           /* all procs are stopped */
+#define JOBDONE 2              /* all procs are completed */
+
+
+struct job {
+       struct procstat ps0;    /* status of process */
+       struct procstat *ps;    /* status or processes when more than one */
+       short nprocs;           /* number of processes */
+       pid_t pgrp;             /* process group of this job */
+       char state;             /* true if job is finished */
+       char used;              /* true if this entry is in used */
+       char changed;           /* true if status has changed */
+       char foreground;        /* true if running in the foreground */
+       char remembered;        /* true if $! referenced */
+#if JOBS
+       char jobctl;            /* job running under job control */
+       struct job *next;       /* job used after this one */
+#endif
+};
+
+
 static struct job *jobtab;     /* array of jobs */
 static int njobs;              /* size of array */
 static pid_t backgndpid = -1;  /* pid of last background process */
@@ -322,11 +358,11 @@ static void
 showjob(struct job *jp, int mode)
 {
        char s[64];
-       char statestr[64];
-       const char *sigstr;
+       char statebuf[16];
+       const char *statestr, *coredump;
        struct procstat *ps;
        struct job *j;
-       int col, curr, i, jobno, prev, procno;
+       int col, curr, i, jobno, prev, procno, status;
        char c;
 
        procno = (mode == SHOWJOBS_PGIDS) ? 1 : jp->nprocs;
@@ -339,38 +375,38 @@ showjob(struct job *jp, int mode)
                        prev = j - jobtab + 1;
        }
 #endif
-       ps = jp->ps + jp->nprocs - 1;
+       coredump = "";
+       status = jp->ps[jp->nprocs - 1].status;
        if (jp->state == 0) {
-               strcpy(statestr, "Running");
+               statestr = "Running";
 #if JOBS
        } else if (jp->state == JOBSTOPPED) {
+               ps = jp->ps + jp->nprocs - 1;
                while (!WIFSTOPPED(ps->status) && ps > jp->ps)
                        ps--;
                if (WIFSTOPPED(ps->status))
                        i = WSTOPSIG(ps->status);
                else
                        i = -1;
-               sigstr = strsignal(i);
-               if (sigstr != NULL)
-                       strcpy(statestr, sigstr);
-               else
-                       strcpy(statestr, "Suspended");
+               statestr = strsignal(i);
+               if (statestr == NULL)
+                       statestr = "Suspended";
 #endif
-       } else if (WIFEXITED(ps->status)) {
-               if (WEXITSTATUS(ps->status) == 0)
-                       strcpy(statestr, "Done");
-               else
-                       fmtstr(statestr, 64, "Done(%d)",
-                           WEXITSTATUS(ps->status));
+       } else if (WIFEXITED(status)) {
+               if (WEXITSTATUS(status) == 0)
+                       statestr = "Done";
+               else {
+                       fmtstr(statebuf, sizeof(statebuf), "Done(%d)",
+                           WEXITSTATUS(status));
+                       statestr = statebuf;
+               }
        } else {
-               i = WTERMSIG(ps->status);
-               sigstr = strsignal(i);
-               if (sigstr != NULL)
-                       strcpy(statestr, sigstr);
-               else
-                       strcpy(statestr, "Unknown signal");
-               if (WCOREDUMP(ps->status))
-                       strcat(statestr, " (core dumped)");
+               i = WTERMSIG(status);
+               statestr = strsignal(i);
+               if (statestr == NULL)
+                       statestr = "Unknown signal";
+               if (WCOREDUMP(status))
+                       coredump = " (core dumped)";
        }
 
        for (ps = jp->ps ; procno > 0 ; ps++, procno--) { /* for each process */
@@ -399,7 +435,8 @@ showjob(struct job *jp, int mode)
                }
                if (ps == jp->ps) {
                        out1str(statestr);
-                       col += strlen(statestr);
+                       out1str(coredump);
+                       col += strlen(statestr) + strlen(coredump);
                }
                do {
                        out1c(' ');
@@ -1016,7 +1053,7 @@ vforkexecshell(struct job *jp, char **argv, char **envp, const char *path, int i
  */
 
 int
-waitforjob(struct job *jp, int *origstatus)
+waitforjob(struct job *jp, int *signaled)
 {
 #if JOBS
        int propagate_int = jp->jobctl && jp->foreground;
@@ -1039,8 +1076,8 @@ waitforjob(struct job *jp, int *origstatus)
                setcurjob(jp);
 #endif
        status = jp->ps[jp->nprocs - 1].status;
-       if (origstatus != NULL)
-               *origstatus = status;
+       if (signaled != NULL)
+               *signaled = WIFSIGNALED(status);
        /* convert to 8 bits */
        if (WIFEXITED(status))
                st = WEXITSTATUS(status);