STATIC void showjob(struct job *jp, pid_t pid, int sformat, int lformat) { char s[64]; struct procstat *ps; 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", (int)ps->pid); goto skip; } if (!lformat && ps != jp->ps && pid == 0) goto skip; if (pid != 0 && pid != ps->pid) goto skip; if (jobno == curr && ps == jp->ps) c = '+'; else if (jobno == prev && ps == jp->ps) c = '-'; else c = ' '; if (ps == jp->ps) fmtstr(s, 64, "[%d] %c ", jobno, c); else fmtstr(s, 64, " %c ", c); out1str(s); col = strlen(s); if (lformat) { fmtstr(s, 64, "%d ", (int)ps->pid); out1str(s); col += strlen(s); } s[0] = '\0'; if (ps != jp->ps) { *s = '\0'; } else if (ps->status == -1) { strcpy(s, "Running"); } else if (WIFEXITED(ps->status)) { if (WEXITSTATUS(ps->status) == 0) strcpy(s, "Done"); else fmtstr(s, 64, "Done (%d)", WEXITSTATUS(ps->status)); } else { #if JOBS if (WIFSTOPPED(ps->status)) i = WSTOPSIG(ps->status); else #endif i = WTERMSIG(ps->status); if ((i & 0x7F) < _NSIG && strsiglist(i & 0x7F)) scopy(strsiglist(i & 0x7F), s); else fmtstr(s, 64, "Signal %d", i & 0x7F); if (WCOREDUMP(ps->status)) strcat(s, " (core dumped)"); } out1str(s); col += strlen(s); do { out1c(' '); col++; } while (col < 30); out1str(ps->cmd); out1c('\n'); skip: if (--procno <= 0) break; } }
STATIC struct job * getjob(char *name) { int jobno; struct job *found, *jp; pid_t pid; int i; if (name == NULL) { #if JOBS currentjob: if ((jp = getcurjob(NULL)) == NULL) error("No current job"); return (jp); #else error("No current job"); #endif } else if (name[0] == '%') { if (is_digit(name[1])) { jobno = number(name + 1); if (jobno > 0 && jobno <= njobs && jobtab[jobno - 1].used != 0) return &jobtab[jobno - 1]; #if JOBS } else if (name[1] == '%' && name[2] == '\0') { goto currentjob; } else if (name[1] == '+' && name[2] == '\0') { goto currentjob; } else if (name[1] == '-' && name[2] == '\0') { if ((jp = getcurjob(NULL)) == NULL || (jp = getcurjob(jp)) == NULL) error("No previous job"); return (jp); #endif } else if (name[1] == '?') { found = NULL; for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { if (jp->used && jp->nprocs > 0 && strstr(jp->ps[0].cmd, name + 2) != NULL) { if (found) error("%s: ambiguous", name); found = jp; } } if (found != NULL) return (found); } else { found = NULL; for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { if (jp->used && jp->nprocs > 0 && prefix(name + 1, jp->ps[0].cmd)) { if (found) error("%s: ambiguous", name); found = jp; } } if (found) return found; } } else if (is_number(name)) { pid = (pid_t)number(name); for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { if (jp->used && jp->nprocs > 0 && jp->ps[jp->nprocs - 1].pid == pid) return jp; } } error("No such job: %s", name); /*NOTREACHED*/ return NULL; }
static void showjob(struct job *jp, int mode) { char s[64]; char statestr[64]; struct procstat *ps; struct job *j; int col, curr, i, jobno, prev, procno; char c; procno = (mode == SHOWJOBS_PGIDS) ? 1 : 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 ps = jp->ps + jp->nprocs - 1; if (jp->state == 0) { strcpy(statestr, "Running"); #if JOBS } else if (jp->state == JOBSTOPPED) { while (!WIFSTOPPED(ps->status) && ps > jp->ps) ps--; if (WIFSTOPPED(ps->status)) i = WSTOPSIG(ps->status); else i = -1; if (i > 0 && i < sys_nsig && sys_siglist[i]) strcpy(statestr, sys_siglist[i]); else strcpy(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 { i = WTERMSIG(ps->status); if (i > 0 && i < sys_nsig && sys_siglist[i]) strcpy(statestr, sys_siglist[i]); else fmtstr(statestr, 64, "Signal %d", i); if (WCOREDUMP(ps->status)) strcat(statestr, " (core dumped)"); } for (ps = jp->ps ; ; ps++) { /* for each process */ if (mode == SHOWJOBS_PIDS || mode == SHOWJOBS_PGIDS) { out1fmt("%d\n", (int)ps->pid); goto skip; } if (mode != SHOWJOBS_VERBOSE && ps != jp->ps) goto skip; if (jobno == curr && ps == jp->ps) c = '+'; else if (jobno == prev && ps == jp->ps) c = '-'; else c = ' '; if (ps == jp->ps) fmtstr(s, 64, "[%d] %c ", jobno, c); else fmtstr(s, 64, " %c ", c); out1str(s); col = strlen(s); if (mode == SHOWJOBS_VERBOSE) { fmtstr(s, 64, "%d ", (int)ps->pid); out1str(s); col += strlen(s); } if (ps == jp->ps) { out1str(statestr); col += strlen(statestr); } do { out1c(' '); col++; } while (col < 30); if (mode == SHOWJOBS_VERBOSE) { out1str(ps->cmd); out1c('\n'); } else printjobcmd(jp); skip: if (--procno <= 0) break; } }