📄 proc.c
字号:
cmdp = command; cmdlen = 0; padd(t); *cmdp++ = 0; if (t->t_dflg & F_PIPEOUT) { pp->p_flags |= PPOU; if (t->t_dflg & F_STDERR) pp->p_flags |= PERR; } pp->p_command = Strsave(command); if (pcurrjob) { struct process *fp; /* careful here with interrupt level */ pp->p_cwd = 0; pp->p_index = pcurrjob->p_index; pp->p_friends = pcurrjob; pp->p_jobid = pcurrjob->p_pid; for (fp = pcurrjob; fp->p_friends != pcurrjob; fp = fp->p_friends) continue; fp->p_friends = pp; } else { pcurrjob = pp; pp->p_jobid = pid; pp->p_friends = pp; pp->p_cwd = dcwd; dcwd->di_count++; if (pmaxindex < BIGINDEX) pp->p_index = ++pmaxindex; else { struct process *np; for (i = 1;; i++) { for (np = proclist.p_next; np; np = np->p_next) if (np->p_index == i) goto tryagain; pp->p_index = i; if (i > pmaxindex) pmaxindex = i; break; tryagain:; } } if (pcurrent == NULL) pcurrent = pp; else if (pprevious == NULL) pprevious = pp; } pp->p_next = proclist.p_next; proclist.p_next = pp; (void) gettimeofday(&pp->p_btime, NULL);}static voidpadd(t) register struct command *t;{ Char **argp; if (t == 0) return; switch (t->t_dtyp) { case NODE_PAREN: pads(STRLparensp); padd(t->t_dspr); pads(STRspRparen); break; case NODE_COMMAND: for (argp = t->t_dcom; *argp; argp++) { pads(*argp); if (argp[1]) pads(STRspace); } break; case NODE_OR: case NODE_AND: case NODE_PIPE: case NODE_LIST: padd(t->t_dcar); switch (t->t_dtyp) { case NODE_OR: pads(STRspor2sp); break; case NODE_AND: pads(STRspand2sp); break; case NODE_PIPE: pads(STRsporsp); break; case NODE_LIST: pads(STRsemisp); break; } padd(t->t_dcdr); return; } if ((t->t_dflg & F_PIPEIN) == 0 && t->t_dlef) { pads((t->t_dflg & F_READ) ? STRspLarrow2sp : STRspLarrowsp); pads(t->t_dlef); } if ((t->t_dflg & F_PIPEOUT) == 0 && t->t_drit) { pads((t->t_dflg & F_APPEND) ? STRspRarrow2 : STRspRarrow); if (t->t_dflg & F_STDERR) pads(STRand); pads(STRspace); pads(t->t_drit); }}static voidpads(cp) Char *cp;{ register int i; /* * Avoid the Quoted Space alias hack! Reported by: * sam@john-bigboote.ICS.UCI.EDU (Sam Horrocks) */ if (cp[0] == STRQNULL[0]) cp++; i = Strlen(cp); if (cmdlen >= PMAXLEN) return; if (cmdlen + i >= PMAXLEN) { (void) Strcpy(cmdp, STRsp3dots); cmdlen = PMAXLEN; cmdp += 4; return; } (void) Strcpy(cmdp, cp); cmdp += i; cmdlen += i;}/* * psavejob - temporarily save the current job on a one level stack * so another job can be created. Used for { } in exp6 * and `` in globbing. */voidpsavejob(){ pholdjob = pcurrjob; pcurrjob = NULL;}/* * prestjob - opposite of psavejob. This may be missed if we are interrupted * somewhere, but pendjob cleans up anyway. */voidprestjob(){ pcurrjob = pholdjob; pholdjob = NULL;}/* * pendjob - indicate that a job (set of commands) has been completed * or is about to begin. */voidpendjob(){ register struct process *pp, *tp; if (pcurrjob && (pcurrjob->p_flags & (PFOREGND | PSTOPPED)) == 0) { pp = pcurrjob; while (pp->p_pid != pp->p_jobid) pp = pp->p_friends; (void) fprintf(cshout, "[%d]", pp->p_index); tp = pp; do { (void) fprintf(cshout, " %d", pp->p_pid); pp = pp->p_friends; } while (pp != tp); (void) fputc('\n', cshout); } pholdjob = pcurrjob = 0;}/* * pprint - print a job */static intpprint(pp, flag) register struct process *pp; bool flag;{ register status, reason; struct process *tp; int jobflags, pstatus; bool hadnl = 1; /* did we just have a newline */ char *format; (void) fpurge(cshout); while (pp->p_pid != pp->p_jobid) pp = pp->p_friends; if (pp == pp->p_friends && (pp->p_flags & PPTIME)) { pp->p_flags &= ~PPTIME; pp->p_flags |= PTIME; } tp = pp; status = reason = -1; jobflags = 0; do { jobflags |= pp->p_flags; pstatus = pp->p_flags & PALLSTATES; if (tp != pp && !hadnl && !(flag & FANCY) && ((pstatus == status && pp->p_reason == reason) || !(flag & REASON))) { (void) fputc(' ', cshout); hadnl = 0; } else { if (tp != pp && !hadnl) { (void) fputc('\n', cshout); hadnl = 1; } if (flag & NUMBER) { if (pp == tp) (void) fprintf(cshout, "[%d]%s %c ", pp->p_index, pp->p_index < 10 ? " " : "", pp == pcurrent ? '+' : (pp == pprevious ? '-' : ' ')); else (void) fprintf(cshout, " "); hadnl = 0; } if (flag & FANCY) { (void) fprintf(cshout, "%5d ", pp->p_pid); hadnl = 0; } if (flag & (REASON | AREASON)) { if (flag & NAME) format = "%-23s"; else format = "%s"; if (pstatus == status) if (pp->p_reason == reason) { (void) fprintf(cshout, format, ""); hadnl = 0; goto prcomd; } else reason = pp->p_reason; else { status = pstatus; reason = pp->p_reason; } switch (status) { case PRUNNING: (void) fprintf(cshout, format, "Running "); hadnl = 0; break; case PINTERRUPTED: case PSTOPPED: case PSIGNALED: /* * tell what happened to the background job * From: Michael Schroeder * <mlschroe@immd4.informatik.uni-erlangen.de> */ if ((flag & REASON) || ((flag & AREASON) && reason != SIGINT && (reason != SIGPIPE || (pp->p_flags & PPOU) == 0))) { (void) fprintf(cshout, format, sys_siglist[(unsigned char) pp->p_reason]); hadnl = 0; } break; case PNEXITED: case PAEXITED: if (flag & REASON) { if (pp->p_reason) (void) fprintf(cshout, "Exit %-18d", pp->p_reason); else (void) fprintf(cshout, format, "Done"); hadnl = 0; } break; default: (void) fprintf(csherr, "BUG: status=%-9o", status); } } }prcomd: if (flag & NAME) { (void) fprintf(cshout, "%s", vis_str(pp->p_command)); if (pp->p_flags & PPOU) (void) fprintf(cshout, " |"); if (pp->p_flags & PERR) (void) fputc('&', cshout); hadnl = 0; } if (flag & (REASON | AREASON) && pp->p_flags & PDUMPED) { (void) fprintf(cshout, " (core dumped)"); hadnl = 0; } if (tp == pp->p_friends) { if (flag & AMPERSAND) { (void) fprintf(cshout, " &"); hadnl = 0; } if (flag & JOBDIR && !eq(tp->p_cwd->di_name, dcwd->di_name)) { (void) fprintf(cshout, " (wd: "); dtildepr(value(STRhome), tp->p_cwd->di_name); (void) fputc(')', cshout); hadnl = 0; } } if (pp->p_flags & PPTIME && !(status & (PSTOPPED | PRUNNING))) { if (!hadnl) (void) fprintf(cshout, "\n\t"); prusage(&zru, &pp->p_rusage, &pp->p_etime, &pp->p_btime); hadnl = 1; } if (tp == pp->p_friends) { if (!hadnl) { (void) fputc('\n', cshout); hadnl = 1; } if (flag & SHELLDIR && !eq(tp->p_cwd->di_name, dcwd->di_name)) { (void) fprintf(cshout, "(wd now: "); dtildepr(value(STRhome), dcwd->di_name); (void) fprintf(cshout, ")\n"); hadnl = 1; } } } while ((pp = pp->p_friends) != tp); if (jobflags & PTIME && (jobflags & (PSTOPPED | PRUNNING)) == 0) { if (jobflags & NUMBER) (void) fprintf(cshout, " "); ptprint(tp); hadnl = 1; } (void) fflush(cshout); return (jobflags);}static voidptprint(tp) register struct process *tp;{ struct timeval tetime, diff; static struct timeval ztime; struct rusage ru; static struct rusage zru; register struct process *pp = tp; ru = zru; tetime = ztime; do { ruadd(&ru, &pp->p_rusage); tvsub(&diff, &pp->p_etime, &pp->p_btime); if (timercmp(&diff, &tetime, >)) tetime = diff; } while ((pp = pp->p_friends) != tp); prusage(&zru, &ru, &tetime, &ztime);}/* * dojobs - print all jobs */void/*ARGSUSED*/dojobs(v, t) Char **v; struct command *t;{ register struct process *pp; register int flag = NUMBER | NAME | REASON; int i; if (chkstop) chkstop = 2; if (*++v) { if (v[1] || !eq(*v, STRml)) stderror(ERR_JOBS); flag |= FANCY | JOBDIR; } for (i = 1; i <= pmaxindex; i++) for (pp = proclist.p_next; pp; pp = pp->p_next) if (pp->p_index == i && pp->p_pid == pp->p_jobid) { pp->p_flags &= ~PNEEDNOTE; if (!(pprint(pp, flag) & (PRUNNING | PSTOPPED))) pflush(pp); break; }}/* * dofg - builtin - put the job into the foreground */void/*ARGSUSED*/dofg(v, t) Char **v; struct command *t;{ register struct process *pp; okpcntl(); ++v; do { pp = pfind(*v); pstart(pp, 1); pjwait(pp); } while (*v && *++v);}/* * %... - builtin - put the job into the foreground */void/*ARGSUSED*/dofg1(v, t) Char **v; struct command *t;{ register struct process *pp; okpcntl(); pp = pfind(v[0]); pstart(pp, 1); pjwait(pp);}/* * dobg - builtin - put the job into the background */void/*ARGSUSED*/dobg(v, t)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -