To be done: get copies of process tables instead of using /dev/(k)mem.
*
* VERY IMPORTANT NOTE:
* To compile ps, the kernel/, fs/ and pm/ source directories must be in
- * ../ relative to the directory where ps is compiled (normally the
+ * ../../ relative to the directory where ps is compiled (normally the
* tools source directory).
*
* If you want your ps to be useable by anyone, you can arrange the
#include "../../kernel/const.h"
#include "../../kernel/type.h"
#include "../../kernel/proc.h"
-#undef printf /* kernel's const.h defined this */
#include "../../servers/pm/mproc.h"
#include "../../servers/fs/fproc.h"
#include "../../servers/fs/const.h"
-#undef printf /* fs's const.h defined this */
/*----- ps's local stuff below this line ------*/
/* Macro to convert memory offsets to rounded kilo-units */
#define off_to_k(off) ((unsigned) (((off) + 512) / 1024))
-/* Number of tasks and processes. */
-int nr_tasks, nr_procs;
+
+/* Number of tasks and processes and addresses of the main process tables. */
+int nr_tasks, nr_procs;
+vir_bytes proc_addr, mproc_addr, fproc_addr;
+extern int errno;
/* Process tables of the kernel, MM, and FS. */
struct proc *ps_proc;
#define L_HEADER " F S UID PID PPID PGRP SZ RECV TTY TIME CMD\n"
#define L_FORMAT "%3o %c %3d %5s %5d %5d %4d %10s %3s %s %s\n"
+
struct pstat { /* structure filled by pstat() */
dev_t ps_dev; /* major/minor of controlling tty */
uid_t ps_ruid; /* real uid */
char *ke_path; /* paths of kernel, */
char *mm_path; /* mm, */
char *fs_path; /* and fs used in ps -U */
- struct psinfo psinfo;
char pid[2 + sizeof(pid_t) * 3];
unsigned long ustime;
char cpu[sizeof(clock_t) * 3 + 1 + 2];
+ struct kinfo kinfo;
+ int s;
(void) signal(SIGSEGV, disaster); /* catch a common crash */
if ((kmemfd = open(KMEM_PATH, O_RDONLY)) == -1) err(KMEM_PATH);
if ((memfd = open(MEM_PATH, O_RDONLY)) == -1) err(MEM_PATH);
if (gettynames() == -1) err("Can't get tty names");
- if (ioctl(memfd, MIOCGPSINFO, (void *) &psinfo) == -1)
- err("can't get PS info from kernel");
- nr_tasks = psinfo.nr_tasks;
- nr_procs = psinfo.nr_procs;
+
+ getsysinfo(PM_PROC_NR, SI_PROC_ADDR, &mproc_addr);
+ getsysinfo(FS_PROC_NR, SI_PROC_ADDR, &fproc_addr);
+ getsysinfo(PM_PROC_NR, SI_KINFO, &kinfo);
+ proc_addr = kinfo.proc_addr;
+ nr_tasks = kinfo.nr_tasks;
+ nr_procs = kinfo.nr_procs;
/* Allocate memory for process tables */
ps_proc = (struct proc *) malloc((nr_tasks + nr_procs) * sizeof(ps_proc[0]));
/* Get kernel process table */
if (addrread(kmemfd, (phys_clicks) 0,
- psinfo.proc, (char *) ps_proc,
+ proc_addr, (char *) ps_proc,
(nr_tasks + nr_procs) * sizeof(ps_proc[0]))
!= (nr_tasks + nr_procs) * sizeof(ps_proc[0]))
err("Can't get kernel proc table from /dev/kmem");
/* Get mm/fs process tables */
if (addrread(memfd, ps_proc[nr_tasks + PM_PROC_NR].p_memmap[D].mem_phys,
- psinfo.mproc, (char *) ps_mproc,
+ mproc_addr, (char *) ps_mproc,
nr_procs * sizeof(ps_mproc[0]))
!= nr_procs * sizeof(ps_mproc[0]))
err("Can't get mm proc table from /dev/mem");
if (addrread(memfd, ps_proc[nr_tasks + FS_PROC_NR].p_memmap[D].mem_phys,
- psinfo.fproc, (char *) ps_fproc,
+ fproc_addr, (char *) ps_fproc,
nr_procs * sizeof(ps_fproc[0]))
!= nr_procs * sizeof(ps_fproc[0]))
err("Can't get fs proc table from /dev/mem");
if (opt_long) printf(L_FORMAT,
buf.ps_flags, buf.ps_state,
- buf.ps_euid, pid, buf.ps_ppid,
+ buf.ps_euid, pid, buf.ps_ppid,
buf.ps_pgrp,
off_to_k((buf.ps_tsize
+ buf.ps_stack - buf.ps_data
bufp->ps_recv = ps_proc[p_ki].p_getfrom;
- bufp->ps_utime = ps_proc[p_ki].user_time;
- bufp->ps_stime = ps_proc[p_ki].sys_time;
+ bufp->ps_utime = ps_proc[p_ki].p_user_time;
+ bufp->ps_stime = ps_proc[p_ki].p_sys_time;
bufp->ps_procargs = ps_mproc[p_nr].mp_procargs;
#define MESS_SIZE (sizeof(message)) /* might need usizeof from fs here */
#define NIL_MESS ((message *) 0)
-struct psinfo { /* information for the ps(1) program */
- u16_t nr_tasks, nr_procs; /* NR_TASKS and NR_PROCS constants. */
- vir_bytes proc, mproc, fproc; /* addresses of the main process tables. */
-};
-
/* This is used to obtain system information through SYS_GETINFO. */
struct kinfo {
phys_bytes code_base; /* base of kernel code */
#define RBT_RESET 4 /* hard reset the system */
#endif
+/* What system info to retrieve with sysgetinfo(). */
+#define SI_KINFO 0 /* get kernel info via PM */
+#define SI_PROC_ADDR 1 /* address of process table */
+#define SI_PROC_TAB 2 /* copy of entire process table */
+
/* NULL must be defined in <unistd.h> according to POSIX Sec. 2.7.1. */
#define NULL ((void *)0)
void *where; /* where to put it */
{
message m;
-
m.m1_i1 = what;
m.m1_p1 = where;
if (_syscall(who, GETSYSINFO, &m) < 0) return(-1);
$(LIBRARY)(getppid.o) \
$(LIBRARY)(getuid.o) \
$(LIBRARY)(getprocnr.o) \
+ $(LIBRARY)(getsysinfo.o) \
$(LIBRARY)(findproc.o) \
$(LIBRARY)(ioctl.o) \
$(LIBRARY)(isatty.o) \
$(LIBRARY)(getppid.o): getppid.s
$(CC1) getppid.s
+$(LIBRARY)(getsysinfo.o): getsysinfo.s
+ $(CC1) getsysinfo.s
+
$(LIBRARY)(getprocnr.o): getprocnr.s
$(CC1) getprocnr.s
zone_t b__v2_ind[V2_INDIRECTS(MAX_BLOCK_SIZE)]; /* V2 indirect block */
d1_inode b__v1_ino[V1_INODES_PER_BLOCK]; /* V1 inode block */
d2_inode b__v2_ino[V2_INODES_PER_BLOCK(MAX_BLOCK_SIZE)]; /* V2 inode block */
- bitchunk_t b__bitmap[BITMAP_CHUNKS(MAX_BLOCK_SIZE)]; /* bit map block */
+ bitchunk_t b__bitmap[FS_BITMAP_CHUNKS(MAX_BLOCK_SIZE)]; /* bit map block */
} b;
/* Header portion of the buffer. */
#define NR_DIR_ENTRIES(b) ((b)/DIR_ENTRY_SIZE) /* # dir entries/blk */
#define SUPER_SIZE usizeof (struct super_block) /* super_block size */
#define PIPE_SIZE(b) (V1_NR_DZONES*(b)) /* pipe size in bytes */
-#define BITMAP_CHUNKS(b) ((b)/usizeof (bitchunk_t))/* # map chunks/blk */
-#define BITCHUNK_BITS (usizeof(bitchunk_t) * CHAR_BIT)
-#define BITS_PER_BLOCK(b) (BITMAP_CHUNKS(b) * BITCHUNK_BITS)
+
+#define FS_BITMAP_CHUNKS(b) ((b)/usizeof (bitchunk_t))/* # map chunks/blk */
+#define FS_BITCHUNK_BITS (usizeof(bitchunk_t) * CHAR_BIT)
+#define FS_BITS_PER_BLOCK(b) (FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS)
/* Derived sizes pertaining to the V1 file system. */
#define V1_ZONE_NUM_SIZE usizeof (zone1_t) /* # bytes in V1 zone */
*===========================================================================*/
PUBLIC int do_getsysinfo()
{
+ struct fproc *proc_addr;
+ vir_bytes src_addr, dst_addr;
+ size_t len;
+ int s;
+
+ switch(m_in.info_what) {
+ case SI_PROC_ADDR:
+ proc_addr = &fproc[0];
+ src_addr = (vir_bytes) &proc_addr;
+ len = sizeof(struct fproc *);
+ break;
+ default:
+ return(EINVAL);
+ }
+
+ dst_addr = (vir_bytes) m_in.info_where;
+ if (OK != (s=sys_datacopy(SELF, src_addr, who, dst_addr, len)))
+ return(s);
return(OK);
+
}
#define svrctl_req m2_i1
#define svrctl_argp m2_p1
#define pm_stime m1_i1
+#define info_what m1_i1
+#define info_where m1_p1
/* The following names are synonyms for the variables in the output message. */
#define reply_type m_type
if (origin >= map_bits) origin = 0; /* for robustness */
/* Locate the starting place. */
- block = origin / BITS_PER_BLOCK(sp->s_block_size);
- word = (origin % BITS_PER_BLOCK(sp->s_block_size)) / BITCHUNK_BITS;
+ block = origin / FS_BITS_PER_BLOCK(sp->s_block_size);
+ word = (origin % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS;
/* Iterate over all blocks plus one, because we start in the middle. */
bcount = bit_blocks + 1;
do {
bp = get_block(sp->s_dev, start_block + block, NORMAL);
- wlim = &bp->b_bitmap[BITMAP_CHUNKS(sp->s_block_size)];
+ wlim = &bp->b_bitmap[FS_BITMAP_CHUNKS(sp->s_block_size)];
/* Iterate over the words in block. */
for (wptr = &bp->b_bitmap[word]; wptr < wlim; wptr++) {
for (i = 0; (k & (1 << i)) != 0; ++i) {}
/* Bit number from the start of the bit map. */
- b = ((bit_t) block * BITS_PER_BLOCK(sp->s_block_size))
- + (wptr - &bp->b_bitmap[0]) * BITCHUNK_BITS
+ b = ((bit_t) block * FS_BITS_PER_BLOCK(sp->s_block_size))
+ + (wptr - &bp->b_bitmap[0]) * FS_BITCHUNK_BITS
+ i;
/* Don't allocate bits beyond the end of the map. */
} else {
start_block = START_BLOCK + sp->s_imap_blocks;
}
- block = bit_returned / BITS_PER_BLOCK(sp->s_block_size);
- word = (bit_returned % BITS_PER_BLOCK(sp->s_block_size)) / BITCHUNK_BITS;
- bit = bit_returned % BITCHUNK_BITS;
+ block = bit_returned / FS_BITS_PER_BLOCK(sp->s_block_size);
+ word = (bit_returned % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS;
+ bit = bit_returned % FS_BITCHUNK_BITS;
mask = 1 << bit;
bp = get_block(sp->s_dev, start_block + block, NORMAL);
return(OK);
}
-/*=====================================================================*
- * do_getsysinfo *
- *=====================================================================*/
+/*===========================================================================*
+ * do_getsysinfo *
+ *===========================================================================*/
PUBLIC int do_getsysinfo()
{
+ struct mproc *proc_addr;
+ vir_bytes src_addr, dst_addr;
+ struct kinfo kinfo;
+ size_t len;
+ int s;
+
+ switch(m_in.info_what) {
+ case SI_KINFO: /* kernel info is obtained via PM */
+ sys_getkinfo(&kinfo);
+ src_addr = (vir_bytes) &kinfo;
+ len = sizeof(struct kinfo);
+ break;
+ case SI_PROC_ADDR: /* get address of PM process table */
+ proc_addr = &mproc[0];
+ src_addr = (vir_bytes) &proc_addr;
+ len = sizeof(struct mproc *);
+ break;
+ default:
+ return(EINVAL);
+ }
+
+ dst_addr = (vir_bytes) m_in.info_where;
+ if (OK != (s=sys_datacopy(SELF, src_addr, who, dst_addr, len)))
+ return(s);
return(OK);
}
-/*=====================================================================*
- * do_getprocnr *
- *=====================================================================*/
+/*===========================================================================*
+ * do_getprocnr *
+ *===========================================================================*/
PUBLIC int do_getprocnr()
{
register struct mproc *rmp;
#ifdef _SIGMESSAGE
#define sig_msg m1_i1
#endif
+#define info_what m1_i1
+#define info_where m1_p1
#define reboot_flag m1_i1
#define reboot_code m1_p1
#define reboot_size m1_i2