home *** CD-ROM | disk | FTP | other *** search
- /*
- * ps.c - a program to print MiNT process statuses
- *
- * Based on the original ps by Tony Reynolds, cctony@sgisci1.ocis.olemiss.edu,
- * and updated by Eric Smith and Allan Pratt.
- * For use with MiNT release 0.9.
- * Compiles with my port of the MiNTlib to Sozobon 2.0, as well as the GCC.
- *
- * $Log: ps.c,v $
- * Revision 0.9 1992/01/15 21:48:22 sozobon
- * dpg's first version.
- * Uses opendir rather than Fsfirst/next.
- * Print owner information, rather than parent process id.
- *
- */
-
- static char *proc =
- "$Id: ps.c,v 0.9 1992/01/15 21:48:22 sozobon Exp sozobon $";
-
- #include <basepage.h>
- #include <dirent.h>
- #include <errno.h>
- #include <ioctl.h>
- #include <pwd.h>
- #include <stat.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
-
- #define PROCDIR "u:/proc"
-
- #define ulong unsigned long
- #define ushort unsigned short
-
- extern int __mint;
-
- /* The following structures are taken from proc.h in the MiNT kernel. */
-
- /* a process context consists, for now, of its registers */
-
- 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) */
- 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;
-
- #define PROC_CTXTS 2
-
- typedef struct proc {
- /* this is stuff that the public can know about */
- /* NOTE: some assembly code (in intr.s and contxt.s) makes
- * assumptions about the offsets of sysstack, ctxt[0], systime,
- * and usrtime.
- */
- long sysstack; /* must be first */
- CONTEXT ctxt[PROC_CTXTS]; /* must be second */
-
- long magic; /* validation for proc struct */
-
- char *base; /* process base page */
- short pid, ppid, pgrp;
- short ruid; /* process real user id */
- short rgid; /* process real group id */
- short euid, egid; /* effective user and group ids */
-
- ushort memflags; /* e.g. malloc from alternate ram */
- short pri; /* base process priority */
- short wait_q; /* current process queue */
- long wait_cond; /* condition we're waiting on */
- /* (also return code from wait) */
-
- /* (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 UNIX) */
-
- short curpri; /* current process priority */
- #define MIN_NICE -20
- #define MAX_NICE 20
- } PROC;
-
- /* different process queues */
-
- #define CURPROC_Q 0
- #define READY_Q 1
- #define WAIT_Q 2
- #define IO_Q 3
- #define ZOMBIE_Q 4
- #define TSR_Q 5
- #define STOP_Q 6
- #define SELECT_Q 7
-
- #define NUM_QUEUES 8
-
- struct status {
- char mint;
- char desc;
- } proc_stat[NUM_QUEUES + 1] = {
- CURPROC_Q, 'R',
- READY_Q, 'R',
- WAIT_Q, 'S',
- IO_Q, 'S',
- SELECT_Q, 'S',
- STOP_Q, 'T',
- ZOMBIE_Q, 'Z',
- TSR_Q, 'X',
- -1, '?'
- }; /* initialized from data in procfs.c */
-
- void
- main(argc, argv)
- int argc;
- char **argv;
- {
- DIR *dirp;
- struct dirent *ent;
- struct stat info;
- int fd;
- int fserror;
- long place;
- short pid,
- ppid,
- pri,
- curpri;
- char *s,
- username[9];
- struct status *statp;
- BASEPAGE bpage; /* process basepage read in here if possible */
- PROC proc; /* process info read in here */
- long ptime;
- long hour,
- min,
- sec,
- frac;
- struct passwd *pwent;
-
- if (chdir(PROCDIR) || !(dirp = opendir("."))) {
- perror(PROCDIR);
- return 1;
- }
-
- printf("USER PID PRI/CUR STAT SIZE TIME COMMAND\n");
- username[8] = '\0';
-
- while (ent = readdir(dirp)) {
- if ((fd = open(ent->d_name, 0)) < 0 || fstat(fd, &info))
- goto next;
-
- /* Should really copy the name elsewhere. */
- for (s = ent->d_name; *s && *s != '.'; s++);
- *s = '\0';
-
- ioctl(fd, PPROCADDR, &place);
- lseek(fd, place, 0);
- read(fd, &proc, sizeof(proc));
-
- if (pwent = getpwuid(proc.ruid))
- strncpy(username, pwent->pw_name, 8);
- else
- strcpy(username, "??user??");
-
- 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 .00x digit) */
-
- ioctl(fd, PBASEADDR, &place);
- lseek(fd, place, 0);
- read(fd, &bpage, sizeof(bpage));
- if (*bpage.p_cmdlin)
- *bpage.p_cmdlin = ' ';
- close(fd);
-
- statp = proc_stat; /* hunt down string referring to process
- * status */
- while (statp->mint != proc.wait_q &&
- statp->mint >= 0)
- statp++;
-
- printf("%-8s %03d %3d/%3d %c %c ", username, proc.pid,
- proc.pri, proc.curpri, statp->desc,
- proc.pri < 0 ? 'N' : proc.pri > 0 ? '<' : ' ');
- if (info.st_size > 1000000L)
- printf("%3ldM ", info.st_size / 1000000L);
- else if (info.st_size > 1000L)
- printf("%3ldk ", info.st_size / 1000L);
- else
- printf("%3ld ", info.st_size);
- if (hour)
- printf("%02ld:%02ld:%02ld", hour, min, sec);
- else
- printf("%02ld:%02ld.%02ld", min, sec, frac);
- printf(" %s%s\n", ent->d_name, bpage.p_cmdlin);
- next:
- }
- closedir(dirp);
- endpwent();
- return 0;
- }
-