/* ps.c: a program to print MiNT process statuses Coded: 3/24/1991 by Tony Reynolds, cctony@sgisci1.ocis.olemiss.edu For use with: MiNT release 0.7 Updated: 3/29/1991 by Eric Smith for MiNT version 0.8 Updated again 8/9/1991 by ERS for MiNT 0.9. Updated some more 11/91 by AKP (shows process time in fractions of a sec). */ #include #include #include #include #include #include #include #include #ifndef PCTXTSIZE #define PCTXTSIZE (('P'<<8) | 3) #endif #define ulong unsigned long struct status { /* defines values for internal->external process states */ int mint; /* what MiNT knows */ char desc[10]; /* a textual description for above */ } proc_stat[] = { 0, "Ready", 0x01, "Ready", 0x20, "Wait ", 0x21, "Sleep", 0x22, "Exit ", 0x02, "TSR ", 0x24, "Stop ", -1, "Unkn " }; /* initialized from data in procfs.c */ extern int __mint; typedef struct _context { long regs[15]; /* registers d0-d7, a0-a6 */ long usp; /* user stack pointer (a7) */ short sr; /* status register */ long pc; /* program counter */ long ssp; /* supervisor stack pointer */ long term_vec; /* GEMDOS terminate vector (0x102) */ /* these fields were added in MiNT 0.9 */ char fstate[216]; /* FPU internal state */ char fregs[12*8]; /* registers fp0-fp7 */ long fctrl[3]; /* FPCR/FPSR/FPIAR */ short sfmt; /* stack frame format identifier */ long iar; /* instruction address */ short internal[4]; /* four words of internal info */ } CONTEXT; struct pinfo { long magic; char *base; short pid, ppid, pgrp; short ruid, rgid; short euid, egid; short memflags; short pri; short wait_q; long wait_cond; /* (all times are in milliseconds) */ ulong systime; /* time spent in kernel */ ulong usrtime; /* time spent out of kernel */ ulong chldstime; /* children's kernel time */ ulong chldutime; /* children's user time */ ulong maxmem; /* max. amount of memory to use */ ulong maxdata; /* max. data region for process */ ulong maxcore; /* max. core memory for process */ ulong maxcpu; /* max. cpu time to use */ short domain; /* process domain (TOS or MiNT) */ short curpri; /* current priority (nice) */ }; /* open the process named "name" */ int open_proc(name) char *name; { static char pname[] = "u:\\proc\\xxxxxxxx.xxx"; strcpy(pname+8, name); return open(pname, 0); } void main(argc, argv) int argc; char **argv; { _DTA mydta; int fd; int fserror=0; long place; short pid, ppid, pri, curpri; char *cmdline; struct status *statp; long ctxtsize; BASEPAGE bpage; /* process basepage read in here if possible */ struct pinfo proc; /* process info read in here */ long ptime; long hour, min, sec, frac; Fsetdta(&mydta); /* give the OS my new DTA */ fserror=Fsfirst("u:\\proc\\*.*", 0x27); if (fserror < 0) { fprintf(stderr, "ps: cannot list processes, MiNT may not be running\n"); exit(1); } printf("PID PPID PRI CURPRI STATUS SIZE TIME COMMAND\n"); /* okay, now run the Fsnext bit through the wringer */ fserror = E_OK; /* set up for the loop */ while (fserror == E_OK ) { fd = open_proc(mydta.dta_name); for (cmdline = mydta.dta_name; *cmdline && *cmdline != '.'; cmdline++) ; *cmdline = 0; if (fd < 0) goto next; ioctl(fd, PPROCADDR, &place); if (ioctl(fd, PCTXTSIZE, &ctxtsize) < 0) { lseek(fd, place+4+2*sizeof(CONTEXT), 0); } else lseek(fd, place, 0); read(fd, &proc, sizeof(proc)); if ((pid = proc.pid) < 0) pid = 0; if ((ppid = proc.ppid) < 0) ppid = 0; pri = proc.pri; curpri = proc.curpri; ptime = proc.systime + proc.usrtime; hour = (ptime/1000/60/60); min = (ptime/1000/60)%60; sec = (ptime/1000)%60; frac = (ptime%1000) / 10; /* (never anything in .001 digit) */ ioctl(fd, PBASEADDR, &place); lseek(fd, place, 0); read(fd, &bpage, sizeof(bpage)); cmdline = bpage.p_cmdlin; if (*cmdline) *cmdline = ' '; close(fd); statp = proc_stat; /* hunt down string referring to process status */ while (statp->mint != mydta.dta_attribute && statp->mint >= 0) statp++; /* PID PPID PRI CURPRI STATUS SIZE TIME COMMAND */ if (hour) { printf("%03d %03d %3d %3d %s %8ld %02ld:%02ld:%02ld %s%s\n", pid, ppid, pri, curpri, statp->desc, mydta.dta_size, hour, min, sec, mydta.dta_name, cmdline); } else { printf("%03d %03d %3d %3d %s %8ld %02d:%02d.%02d %s%s\n", pid, ppid, pri, curpri, statp->desc, mydta.dta_size, min, sec, frac, mydta.dta_name, cmdline); } next: fserror = Fsnext(); } exit(0); }