|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 9645 (0x25ad) Types: TextFile Notes: UNIX file Names: »ps.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─⟦this⟧ »cmd/ps.c«
/* * Print out process statuses. */ #include <stdio.h> #include <ctype.h> #include <const.h> #include <l.out.h> #include <pwd.h> #include <proc.h> #include <sched.h> #include <seg.h> #include <stat.h> #include <uproc.h> /* * Maximum sizes. */ #define ARGSIZE 512 /* * Functions to see if a pointer is in alloc space and to map a * pointer from alloc space to this process. */ #define range(p) (p>=(char *)(aend) && p<(char *)(aend)+casize) #define map(p) (&allp[(char *)p - (char *)aend]) /* * For easy referencing. */ #define aprocq nl[0].n_value #define autime nl[1].n_value #define astime nl[2].n_value #define aasize nl[3].n_value #define aend nl[4].n_value /* * Variables. */ int aflag; /* All processes */ int dflag; /* Debug flag */ int fflag; /* Print out all fields */ int lflag; /* Long format */ int mflag; /* Print scheduling values */ int nflag; /* No header */ int rflag; /* Print out real sizes */ int tflag; /* Print times */ int wflag; /* Wide format */ int xflag; /* Get special processes */ dev_t ttdev; /* Terminal device */ /* * Table for namelist. */ struct nlist nl[] ={ "procq_", 0, 0, "utimer_", 0, 0, "stimer_", 0, 0, "asize_", 0, 0, "end_", 0, 0, "" }; /* * Symbols. */ char *allp; /* Pointer to alloc space */ char *kfile; /* Kernel data memory file */ char *nfile; /* Namelist file */ char *mfile; /* Memory file */ char *dfile; /* Swap file */ char argp[ARGSIZE]; /* Arguments */ int kfd; /* Kernel memory file descriptor */ int mfd; /* Memory file descriptor */ int dfd; /* Swap file descriptor */ struct uproc u; /* User process area */ int cutime; /* Unsigned time */ PROC cprocq; /* Process queue header */ unsigned casize; /* Size of alloc area */ char *uname(); main(argc, argv) char *argv[]; { register int i; register char *cp; initialise(); for (i=1; i<argc; i++) { for (cp=&argv[i][0]; *cp; cp++) { switch (*cp) { case '-': continue; case 'a': aflag++; continue; case 'c': if (++i >= argc) usage(); nfile = argv[i]; continue; case 'd': dflag++; continue; case 'f': fflag++; continue; case 'k': if (++i >= argc) usage(); mfile = argv[i]; continue; case 'l': lflag++; continue; case 'm': mflag++; continue; case 'n': nflag++; continue; case 'r': rflag++; continue; case 't': tflag++; continue; case 'w': wflag++; continue; case 'x': xflag++; continue; default: usage(); } } } execute(); exit(0); } /* * Initialise. */ initialise() { register char *cp; aflag = 0; lflag = 0; mflag = 0; nflag = 0; xflag = 0; nfile = "/coherent"; kfile = "/dev/kmem"; mfile = "/dev/mem"; dfile = "/dev/swap"; if ((cp=malloc(BUFSIZ)) != NULL) setbuf(stdout, cp); } /* * Print out usage. */ usage() { panic("Usage: ps [-acdklmnrtwx]"); } /* * Print out information about processes. */ execute() { int c, l; register PROC *pp1, *pp2; nlist(nfile, nl); if (nl[0].n_type == 0) panic("Bad namelist file %s", nfile); if ((mfd=open(mfile, 0)) < 0) panic("Cannot open %s", mfile); if ((kfd = open(kfile, 0)) < 0) panic("Cannot open %s", kfile); if ((dfd=open(dfile, 0)) < 0) panic("Cannot open %s", dfile); kread((long)aasize, &casize, sizeof (casize)); kread((long)aprocq, &cprocq, sizeof (cprocq)); if ((allp=malloc(casize)) == NULL) panic("Out of core"); kread((long)aend, allp, casize); kread((long)autime, &cutime, sizeof (cutime)); settdev(); l = 9; if (dflag) l += 7; if (lflag) l += 31; if (mflag) l += 26; if (tflag) l += 12; if (nflag == 0) { if (dflag) printf(" "); printf("TTY PID"); if (lflag) printf(" PPID UID K F S EVENT"); if (mflag) printf(" CVAL SVAL IVAL RVAL"); if (tflag) printf(" UTIME STIME"); putchar('\n'); fflush(stdout); } pp1 = &cprocq; while ((pp2=pp1->p_nback) != aprocq) { if (range((char *)pp2) == 0) panic("Fragmented list"); pp1 = (PROC *) map(pp2); if (xflag==0 && pp1->p_ttdev==NODEV) continue; if (aflag==0 && pp1->p_ttdev!=ttdev) continue; if (dflag) printf("%06o ", pp2); ptty(pp1); printf(" %5d", pp1->p_pid); if (lflag) { printf(" %5d", pp1->p_ppid); printf(" %6s", uname(pp1)); psize(pp1); printf(" %4o", pp1->p_flags); printf(" %c", c=state(pp1, pp2)); if (c == 'S') { putchar(' '); printf(AFMT, pp1->p_event); } else { if (fflag) printf(" -"); else printf(" "); } } if (mflag) { printf(" %5u", cval(pp1, pp2)); printf(" %5u", pp1->p_sval); printf(" %6d", pp1->p_ival); printf(" %6d", pp1->p_rval); } if (tflag) { ptime(pp1->p_utime); ptime(pp1->p_stime); } printf(" "); printl(pp1, (wflag?132:80)-l-1); putchar('\n'); fflush(stdout); } } /* * Set our terminal device. */ settdev() { register PROC *pp1, *pp2; register int p; p = getpid(); pp1 = &cprocq; while ((pp2=pp1->p_nforw) != aprocq) { if (range((char *)pp2) == 0) break; pp1 = (PROC *) map(pp2); if (pp1->p_pid == p) { ttdev = pp1->p_ttdev; return; } } ttdev = NODEV; } /* * Print out a terminal name. */ ptty(pp) register PROC *pp; { register int d; if ((d=pp->p_ttdev) == NODEV) { printf("??:"); return; } printf("%o", major(d)); if (minor(d) < 10) printf("%d", minor(d)); else printf("%c", 'a'-10+minor(d)); printf(":"); } /* * Given a process, return it's user name. */ char * uname(pp) register PROC *pp; { static char name[8]; register struct passwd *pwp; if ((pwp=getpwuid(pp->p_ruid)) != NULL) return (pwp->pw_name); sprintf(name, "%d", pp->p_ruid); return (name); } /* * Return the core value for a process. */ cval(pp1, pp2) register PROC *pp1, *pp2; { unsigned u; register PROC *pp3, *pp4; if (pp1->p_state == PSSLEEP) { u = (cutime-pp1->p_lctim) * 1; if (pp1->p_cval+u > pp1->p_cval) return (pp1->p_cval+u); return (-1); } u = 0; pp3 = &cprocq; while ((pp4=pp3->p_lforw) != aprocq) { if (range((char *)pp4) == 0) break; pp3 = (PROC *) map(pp4); u -= pp3->p_cval; if (pp2 == pp4) return (u); } if (pp1->p_pid == getpid()) return (pp1->p_cval); return (0); } /* * Return the size in K of the given process. */ psize(pp) register PROC *pp; { long l; register SEG *sp; register int n; l = 0; for (n=0; n<NUSEG+1; n++) { if (rflag == 0) if (n==SIUSERP || n==SIAUXIL) continue; if ((sp=pp->p_segp[n]) == NULL) continue; if (range((char *)sp) == 0) { printf(" ?K"); return; } sp = (SEG *) map(sp); l += ctob(sp->s_size); } if (l != 0) printf("%3ldK", l/1024); else { if (fflag) printf(" -"); else printf(" "); } } /* * Get the state of the process. */ state(pp1, pp2) register PROC *pp1, *pp2; { register int s; s = pp1->p_state; if (s == PSSLEEP) { if ((PROC *)pp1->p_event == pp2) return ('W'); if ((pp1->p_flags&PFSTOP) != 0) return ('T'); return ('S'); } if (s == PSRUN) return ('R'); if (s == PSDEAD) return ('Z'); return ('?'); } /* * Given a time in HZ, print it out. */ ptime(l) long l; { register unsigned m; if ((l=(l+HZ/2)/HZ) == 0) { if (fflag) printf(" -"); else printf(" "); return; } if ((m=l/60) >= 100) { printf("%6d", m); return; } printf(" %2d:%02d", m, (unsigned)l%60); } /* * Print out the command line of a process. */ printl(pp, m) register PROC *pp; { register char *cp; register int c; register int argc; register int n; register SEG *sp; if (pp->p_state == PSDEAD) return; if (pp->p_pid == 0) { printf("<idle>"); return; } if (pp->p_event == astime) { printf("<swap>"); return; } if ((pp->p_flags & PFSLIB) != 0) { printf("<slib>"); return; } if (segread(pp->p_segp[SIUSERP], 0, &u, sizeof (u)) == 0) return; if ((sp = pp->p_segp[SISTACK]) == NULL) sp = pp->p_segp[SIPDATA]; n = segread(sp, (unsigned)(u.u_argp-u.u_segl[SISTACK].sr_base), argp, sizeof (argp)); if (n == 0) return; if ((argc=u.u_argc) <= 0) return; m -= 2; cp = argp; while (argc--) { while ((c=*cp++) != '\0') { if (!isascii(c) || !isprint(c)) return; if (m-- == 0) return; putchar(c); } if (m-- == 0) return; if (argc != 0) putchar(' '); } } /* * Given a segment pointer `sp' and an offset into the segment, * `s', read `n' bytes from the segment into the buffer `bp'. */ segread(sp, s, bp, n) SEG *sp; char *bp; { register SEG *sp1; if (range((char *)sp) == 0) return (0); sp1 = (SEG *) map(sp); if ((sp1->s_flags&SFCORE) != 0) mread(ctob((long)sp1->s_mbase) + s, bp, n); else dread((long)sp1->s_dbase*BSIZE + s, bp, n); return (1); } /* * Read `n' bytes into the buffer `bp' from kernel memory * starting at seek position `s'. */ kread(s, bp, n) long s; char *bp; { #if 1 unsigned x; x = s; s = x; #endif lseek(kfd, s, 0); if (read(kfd, bp, n) != n) panic("Kernel memory read error"); } /* * Read `n' bytes into the buffer `bp' from absolute memory * starting at seek position `s'. */ mread(s, bp, n) long s; char *bp; { lseek(mfd, s, 0); if (read(mfd, bp, n) != n) panic("Memory read error"); } /* * Read `n' bytes into the buffer `bp' from the swap file * starting at seek position `s'. */ dread(s, bp, n) long s; char *bp; { lseek(dfd, s, 0); if (read(dfd, bp, n) != n) panic("Swap read error"); } /* * Print out an error message and exit. */ panic(a1) char *a1; { fflush(stdout); fprintf(stderr, "%r", &a1); fprintf(stderr, "\n"); exit(1); }