Initial Import from SVN
This commit is contained in:
42
src/cmd/pstat/Makefile
Normal file
42
src/cmd/pstat/Makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Should be installed with kmem group.
|
||||
#
|
||||
TOPSRC = $(shell cd ../../..; pwd)
|
||||
include $(TOPSRC)/target.mk
|
||||
|
||||
CFLAGS += -Werror
|
||||
|
||||
SRCS = pstat.c
|
||||
OBJS = pstat.o
|
||||
MAN = pstat.0
|
||||
MANSRC = pstat.8
|
||||
|
||||
all: pstat ${MAN}
|
||||
|
||||
pstat: ${OBJS}
|
||||
${CC} ${LDFLAGS} -o pstat.elf ${OBJS} ${LIBS}
|
||||
${OBJDUMP} -S pstat.elf > pstat.dis
|
||||
${SIZE} pstat.elf
|
||||
${ELF2AOUT} pstat.elf $@ && rm pstat.elf
|
||||
|
||||
${MAN}: ${MANSRC}
|
||||
${MANROFF} ${MANSRC} > ${MAN}
|
||||
|
||||
clean:
|
||||
rm -f *.o *.elf ${MAN} pstat *.elf *.dis tags *~
|
||||
|
||||
depend: ${SRCS}
|
||||
mkdep ${CFLAGS} ${SRCS}
|
||||
|
||||
install: pstat
|
||||
cp ${MAN} ${DESTDIR}/share/man/cat8/
|
||||
install -m 2755 pstat ${DESTDIR}/sbin/pstat
|
||||
|
||||
lint: ${SRCS}
|
||||
lint -hax ${SRCS}
|
||||
|
||||
tags: ${SRCS}
|
||||
ctags ${SRCS}
|
||||
|
||||
# DO NOT DELETE THIS LINE -- mkdep uses it.
|
||||
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
|
||||
358
src/cmd/pstat/pstat.8
Normal file
358
src/cmd/pstat/pstat.8
Normal file
@@ -0,0 +1,358 @@
|
||||
.\" Copyright (c) 1980 Regents of the University of California.
|
||||
.\" All rights reserved. The Berkeley software License Agreement
|
||||
.\" specifies the terms and conditions for redistribution.
|
||||
.\"
|
||||
.\" @(#)pstat.8 6.3.2 (2.11BSD) 1997/9/2
|
||||
.\"
|
||||
.TH PSTAT 8 "September 2, 1997"
|
||||
.UC 4
|
||||
.SH NAME
|
||||
pstat \- print system facts
|
||||
.SH SYNOPSIS
|
||||
.B /usr/sbin/pstat
|
||||
.B \-aixptufT
|
||||
[
|
||||
.B suboptions
|
||||
] [
|
||||
.B system
|
||||
] [
|
||||
.B corefile
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.I Pstat
|
||||
interprets the contents of certain system tables.
|
||||
If
|
||||
.I corefile
|
||||
is given, the tables are sought there, otherwise
|
||||
in
|
||||
.I /dev/kmem.
|
||||
The required namelist is taken from
|
||||
.I /vmunix
|
||||
unless
|
||||
.I system
|
||||
is specified.
|
||||
Options are
|
||||
.TP \w'WCHAN\ 'u
|
||||
.B \-a
|
||||
Under
|
||||
.BR \-p ,
|
||||
describe all process slots rather than just active ones.
|
||||
.TP
|
||||
.B \-i
|
||||
Print the inode table with the these headings:
|
||||
.IP LOC
|
||||
The core location of this table entry.
|
||||
.PD 0
|
||||
.IP FLAGS
|
||||
Miscellaneous state variables encoded thus:
|
||||
.RS
|
||||
.IP L
|
||||
locked
|
||||
.IP U
|
||||
update time
|
||||
.RI ( fs (5))
|
||||
must be corrected
|
||||
.IP A
|
||||
access time must be corrected
|
||||
.IP M
|
||||
file system is mounted here
|
||||
.IP W
|
||||
wanted by another process (L flag is on)
|
||||
.IP T
|
||||
contains a text file
|
||||
.IP C
|
||||
changed time must be corrected
|
||||
.IP S
|
||||
shared lock applied
|
||||
.IP E
|
||||
exclusive lock applied
|
||||
.IP Z
|
||||
someone waiting for a lock
|
||||
.RE
|
||||
.IP CNT
|
||||
Number of open file table entries for this inode.
|
||||
.IP DEV
|
||||
Major and minor device number of file system in which
|
||||
this inode resides.
|
||||
.IP RDC
|
||||
Reference count of shared locks on the inode.
|
||||
.IP WRC
|
||||
Reference count of exclusive locks on the inode (this may
|
||||
be > 1 if, for example, a file descriptor is inherited across a fork).
|
||||
.IP INO
|
||||
I-number within the device.
|
||||
.IP MODE
|
||||
Mode bits, see
|
||||
.IR chmod (2).
|
||||
.IP NLK
|
||||
Number of links to this inode.
|
||||
.IP UID
|
||||
User ID of owner.
|
||||
.IP SIZ/DEV
|
||||
Number of bytes in an ordinary file, or
|
||||
major and minor device of special file.
|
||||
.PD
|
||||
.TP
|
||||
.B \-x
|
||||
Print the text table with these headings:
|
||||
.IP LOC
|
||||
The core location of this table entry.
|
||||
.PD 0
|
||||
.IP FLAGS
|
||||
Miscellaneous state variables encoded thus:
|
||||
.RS
|
||||
.IP T
|
||||
.IR ptrace (2)
|
||||
in effect
|
||||
.IP W
|
||||
text not yet written on swap device
|
||||
.IP L
|
||||
loading in progress
|
||||
.IP K
|
||||
locked
|
||||
.IP w
|
||||
wanted (L flag is on)
|
||||
.IP P
|
||||
resulted from demand-page-from-inode exec format (see
|
||||
.IR execve (2))
|
||||
.RE
|
||||
.PD
|
||||
.IP DADDR
|
||||
Disk address in swap, measured in multiples of 512 bytes.
|
||||
.IP CADDR
|
||||
Head of a linked list of loaded processes using this text segment.
|
||||
.IP RSS
|
||||
Size of resident text, measured in multiples of 512 bytes.
|
||||
.IP SIZE
|
||||
Size of text segment, measured in multiples of 512 bytes.
|
||||
.IP IPTR
|
||||
Core location of corresponding inode.
|
||||
.IP CNT
|
||||
Number of processes using this text segment.
|
||||
.IP CCNT
|
||||
Number of processes in core using this text segment.
|
||||
.IP FORW
|
||||
Forward link in free list.
|
||||
.IP BACK
|
||||
Backward link in free list.
|
||||
.PD
|
||||
.TP
|
||||
.B \-p
|
||||
Print process table for active processes with these headings:
|
||||
.IP LOC
|
||||
The core location of this table entry.
|
||||
.PD 0
|
||||
.IP S
|
||||
Run state encoded thus:
|
||||
.RS
|
||||
.IP 0
|
||||
no process
|
||||
.IP 1
|
||||
waiting for some event
|
||||
.IP 3
|
||||
runnable
|
||||
.IP 4
|
||||
being created
|
||||
.IP 5
|
||||
being terminated
|
||||
.IP 6
|
||||
stopped (by signal or under trace)
|
||||
.RE
|
||||
.IP F
|
||||
Miscellaneous state variables, or'ed together (hexadecimal):
|
||||
.RS
|
||||
.IP 0001 9n
|
||||
loaded
|
||||
.IP 0002
|
||||
system process (swapper)
|
||||
.IP 0004
|
||||
locked for swap out
|
||||
.IP 0008
|
||||
swap save area
|
||||
.IP 0010
|
||||
traced
|
||||
.IP 0020
|
||||
used in tracing
|
||||
.IP 0040
|
||||
user settable lock in core
|
||||
.IP 0100
|
||||
process resulted from
|
||||
.IR vfork (2)
|
||||
.IP 0200
|
||||
parent in vfork, waiting for child
|
||||
.IP 0400
|
||||
parent has released child in vfork
|
||||
.IP 1000
|
||||
detached inherited by init
|
||||
.IP 2000
|
||||
no SIGCHLD signal to parent
|
||||
.IP 4000
|
||||
selecting; wakeup/waiting danger
|
||||
.RE
|
||||
.IP PRI
|
||||
Scheduling priority, see
|
||||
.IR setpriority (2).
|
||||
.IP SIG
|
||||
Signals received (signals 1-32 coded in bits 0-31),
|
||||
.IP UID
|
||||
Real user ID.
|
||||
.IP SLP
|
||||
Amount of time process has been blocked.
|
||||
.IP TIM
|
||||
Time resident in seconds; times over 127 coded as 127.
|
||||
.IP CPU
|
||||
Weighted integral of CPU time, for scheduler.
|
||||
.IP NI
|
||||
Nice level,
|
||||
see
|
||||
.IR setpriority (2).
|
||||
.IP PGRP
|
||||
Process number of root of process group.
|
||||
.IP PID
|
||||
The process ID number.
|
||||
.IP PPID
|
||||
The process ID of parent process.
|
||||
.IP ADDR
|
||||
If in core, the page frame number of the first page of the `u-area' of
|
||||
the process.
|
||||
If swapped out, the position in the swap area
|
||||
measured in multiples of 512 bytes.
|
||||
.IP RSS
|
||||
Resident set size \- the number of physical page frames allocated
|
||||
to this process.
|
||||
.IP SRSS
|
||||
RSS at last swap (0 if never swapped).
|
||||
.IP SIZE
|
||||
Virtual size of process image (data+stack) in multiples of 512 bytes.
|
||||
.IP WCHAN
|
||||
Wait channel number of a waiting process.
|
||||
.IP LINK
|
||||
Link pointer in list of runnable processes.
|
||||
.IP TEXTP
|
||||
If text is pure, pointer to location of text table entry.
|
||||
.PD
|
||||
.TP
|
||||
.B \-t
|
||||
Print table for terminals
|
||||
with these headings:
|
||||
.IP RAW
|
||||
Number of characters in raw input queue.
|
||||
.PD 0
|
||||
.IP CAN
|
||||
Number of characters in canonicalized input queue.
|
||||
.IP OUT
|
||||
Number of characters in putput queue.
|
||||
.IP MODE
|
||||
See
|
||||
.IR tty (4).
|
||||
.IP ADDR
|
||||
Physical device address.
|
||||
.IP DEL
|
||||
Number of delimiters (newlines) in canonicalized input queue.
|
||||
.IP COL
|
||||
Calculated column position of terminal.
|
||||
.IP STATE
|
||||
Miscellaneous state variables encoded thus:
|
||||
.RS
|
||||
.IP T
|
||||
delay timeout in progress
|
||||
.IP W
|
||||
waiting for open to complete
|
||||
.IP O
|
||||
open
|
||||
.IP F
|
||||
outq has been flushed during DMA
|
||||
.IP C
|
||||
carrier is on
|
||||
.IP B
|
||||
busy doing output
|
||||
.IP A
|
||||
process is awaiting output
|
||||
.IP X
|
||||
open for exclusive use
|
||||
.IP S
|
||||
output stopped
|
||||
.IP H
|
||||
hangup on close
|
||||
.RE
|
||||
.IP PGRP
|
||||
Process group for which this is controlling terminal.
|
||||
.IP DISC
|
||||
Line discipline; blank is old tty OTTYDISC or ``new tty'' for NTTYDISC
|
||||
or ``net'' for NETLDISC (see
|
||||
.IR bk (4)).
|
||||
.PD
|
||||
.TP
|
||||
.B \-u
|
||||
print information about a user process;
|
||||
the next argument is its address as given
|
||||
by
|
||||
.IR ps (1).
|
||||
The process must be in main memory, or the file used can
|
||||
be a core image and the address 0.
|
||||
Only the fields located in the first page cluster can be located
|
||||
succesfully if the process is in main memory.
|
||||
.TP
|
||||
.B \-f
|
||||
Print the open file table with these headings:
|
||||
.IP LOC
|
||||
The core location of this table entry.
|
||||
.IP TYPE
|
||||
The type of object the file table entry points to.
|
||||
.PD 0
|
||||
.IP FLG
|
||||
Miscellaneous state variables encoded thus:
|
||||
.RS
|
||||
.IP R
|
||||
open for reading
|
||||
.IP W
|
||||
open for writing
|
||||
.IP A
|
||||
open for appending
|
||||
.IP S
|
||||
shared lock present
|
||||
.IP X
|
||||
exclusive lock present
|
||||
.IP I
|
||||
signal pgrp when data ready
|
||||
.RE
|
||||
.IP CNT
|
||||
Number of processes that know this open file.
|
||||
.IP MSG
|
||||
Number of messages outstanding for this file.
|
||||
.IP DATA
|
||||
The location of the inode table entry or socket structure for this file.
|
||||
.IP OFFSET
|
||||
The file offset (see
|
||||
.IR lseek (2)).
|
||||
.PD
|
||||
.PP
|
||||
.B \-s
|
||||
print information about swap space usage: the number of (1k byte) pages used
|
||||
and free is given as well as the number of used pages which belong
|
||||
to text images.
|
||||
.PP
|
||||
.B \-T
|
||||
prints the number of used and free slots in the several system tables
|
||||
and is useful for checking to see how full system tables have become if the
|
||||
system is under heavy load.
|
||||
.SH FILES
|
||||
.ta \w'/dev/kmem 'u
|
||||
/vmunix namelist
|
||||
.br
|
||||
/dev/kmem default source of tables
|
||||
.SH SEE ALSO
|
||||
iostat(1),
|
||||
ps(1),
|
||||
systat(1),
|
||||
vmstat(1),
|
||||
stat(2),
|
||||
fs(5),
|
||||
.br
|
||||
K. Thompson,
|
||||
.I UNIX Implementation
|
||||
.SH BUGS
|
||||
It would be very useful if the system recorded \*(lqmaximum occupancy\*(rq
|
||||
on the tables reported by
|
||||
.B \-T;
|
||||
even more useful if these tables were dynamically allocated.
|
||||
556
src/cmd/pstat/pstat.c
Normal file
556
src/cmd/pstat/pstat.c
Normal file
@@ -0,0 +1,556 @@
|
||||
/*
|
||||
* Print system stuff
|
||||
*
|
||||
* Copyright (c) 1980 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#define KERNEL
|
||||
#include <sys/file.h>
|
||||
#include <sys/user.h>
|
||||
#undef KERNEL
|
||||
#include <sys/proc.h>
|
||||
#include <sys/inode.h>
|
||||
#include <sys/map.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/vm.h>
|
||||
#include <nlist.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *fcore = "/dev/kmem";
|
||||
char *fmem = "/dev/mem";
|
||||
int fc, fm;
|
||||
|
||||
struct nlist nl[] = {
|
||||
#define SINODE 0
|
||||
{ "_inode" },
|
||||
#define SPROC 1
|
||||
{ "_proc" },
|
||||
#define SKL 2
|
||||
{ "_cnttys" },
|
||||
#define SFIL 3
|
||||
{ "_file" },
|
||||
#define SNSWAP 4
|
||||
{ "_nswap" },
|
||||
#define SWAPMAP 5
|
||||
{ "_swapmap" },
|
||||
#define SNPROC 6
|
||||
{ "_nproc" },
|
||||
{ "" }
|
||||
};
|
||||
|
||||
int inof;
|
||||
int prcf;
|
||||
int ttyf;
|
||||
int usrf;
|
||||
long ubase;
|
||||
int filf;
|
||||
int swpf;
|
||||
int totflg;
|
||||
int allflg;
|
||||
int kflg;
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
register char *argp;
|
||||
int allflags;
|
||||
|
||||
argc--, argv++;
|
||||
while (argc > 0 && **argv == '-') {
|
||||
argp = *argv++;
|
||||
argp++;
|
||||
argc--;
|
||||
while (*argp++)
|
||||
switch (argp[-1]) {
|
||||
|
||||
case 'T':
|
||||
totflg++;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
allflg++;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
inof++;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
kflg++;
|
||||
fcore = fmem = "/core";
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
prcf++;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
ttyf++;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
if (argc == 0)
|
||||
break;
|
||||
argc--;
|
||||
usrf++;
|
||||
sscanf( *argv++, "%lx", &ubase);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
filf++;
|
||||
break;
|
||||
case 's':
|
||||
swpf++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (argc>0) {
|
||||
fcore = fmem = argv[0];
|
||||
kflg++;
|
||||
}
|
||||
if ((fc = open(fcore, 0)) < 0) {
|
||||
printf("Can't find %s\n", fcore);
|
||||
exit(1);
|
||||
}
|
||||
if ((fm = open(fmem, 0)) < 0) {
|
||||
printf("Can't find %s\n", fmem);
|
||||
exit(1);
|
||||
}
|
||||
knlist(nl);
|
||||
|
||||
if (nl[0].n_value == 0) {
|
||||
printf("no namelist, n_type: %d n_value: %x n_name: %s\n", nl[0].n_type, nl[0].n_value, nl[0].n_name);
|
||||
exit(1);
|
||||
}
|
||||
if (! (filf | totflg | inof | prcf | ttyf | usrf | swpf))
|
||||
filf++;
|
||||
|
||||
if (filf||totflg)
|
||||
dofile();
|
||||
if (inof||totflg)
|
||||
doinode();
|
||||
if (prcf||totflg)
|
||||
doproc();
|
||||
if (ttyf)
|
||||
dotty();
|
||||
if (usrf)
|
||||
dousr();
|
||||
if (swpf||totflg)
|
||||
doswap();
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
printf("usage: pstat -[aikptfsT] [-u [ubase]] [core]\n");
|
||||
}
|
||||
|
||||
doinode()
|
||||
{
|
||||
register struct inode *ip;
|
||||
struct inode *xinode;
|
||||
register int nin;
|
||||
u_int ainode;
|
||||
|
||||
nin = 0;
|
||||
xinode = (struct inode *)calloc(NINODE, sizeof (struct inode));
|
||||
ainode = nl[SINODE].n_value;
|
||||
if (xinode == NULL) {
|
||||
fprintf(stderr, "can't allocate memory for inode table\n");
|
||||
return;
|
||||
}
|
||||
lseek(fc, (off_t)ainode, 0);
|
||||
read(fc, xinode, NINODE * sizeof(struct inode));
|
||||
for (ip = xinode; ip < &xinode[NINODE]; ip++)
|
||||
if (ip->i_count)
|
||||
nin++;
|
||||
if (totflg) {
|
||||
printf("%3d/%3d inodes\n", nin, NINODE);
|
||||
return;
|
||||
}
|
||||
printf("%d/%d active inodes\n", nin, NINODE);
|
||||
printf(" LOC FLAGS CNT DEVICE RDC WRC INO MODE NLK UID SIZE/DEV FS\n");
|
||||
for (ip = xinode; ip < &xinode[NINODE]; ip++) {
|
||||
if (ip->i_count == 0)
|
||||
continue;
|
||||
printf("%08x ", ainode + (ip - xinode)*sizeof (*ip));
|
||||
putf((long)ip->i_flag&ILOCKED, 'L');
|
||||
putf((long)ip->i_flag&IUPD, 'U');
|
||||
putf((long)ip->i_flag&IACC, 'A');
|
||||
putf((long)ip->i_flag&IMOUNT, 'M');
|
||||
putf((long)ip->i_flag&IWANT, 'W');
|
||||
putf((long)ip->i_flag&ITEXT, 'T');
|
||||
putf((long)ip->i_flag&ICHG, 'C');
|
||||
putf((long)ip->i_flag&ISHLOCK, 'S');
|
||||
putf((long)ip->i_flag&IEXLOCK, 'E');
|
||||
putf((long)ip->i_flag&ILWAIT, 'Z');
|
||||
putf((long)ip->i_flag&IPIPE, 'P');
|
||||
putf((long)ip->i_flag&IMOD, 'm');
|
||||
putf((long)ip->i_flag&IRENAME, 'r');
|
||||
putf((long)ip->i_flag&IXMOD, 'x');
|
||||
printf("%4d", ip->i_count);
|
||||
printf("%4d,%3d", major(ip->i_dev), minor(ip->i_dev));
|
||||
printf("%4d", ip->i_flag&IPIPE ? 0 : ip->i_shlockc);
|
||||
printf("%4d", ip->i_flag&IPIPE ? 0 : ip->i_exlockc);
|
||||
printf("%6u ", ip->i_number);
|
||||
printf("%7.1o", ip->i_mode);
|
||||
printf("%4d", ip->i_nlink);
|
||||
printf("%5u", ip->i_uid);
|
||||
if ((ip->i_mode&IFMT)==IFBLK || (ip->i_mode&IFMT)==IFCHR)
|
||||
printf("%6d,%3d", major(ip->i_rdev), minor(ip->i_rdev));
|
||||
else
|
||||
printf("%10ld", ip->i_size);
|
||||
printf(" %08x", ip->i_fs);
|
||||
printf("\n");
|
||||
}
|
||||
free(xinode);
|
||||
}
|
||||
|
||||
u_int
|
||||
getuint(loc)
|
||||
off_t loc;
|
||||
{
|
||||
u_int word;
|
||||
|
||||
lseek(fc, loc, 0);
|
||||
read(fc, &word, sizeof (word));
|
||||
|
||||
return (word);
|
||||
}
|
||||
|
||||
putf(v, n)
|
||||
long v;
|
||||
char n;
|
||||
{
|
||||
if (v)
|
||||
printf("%c", n);
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
doproc()
|
||||
{
|
||||
struct proc *xproc;
|
||||
u_int nproc, aproc;
|
||||
register struct proc *pp;
|
||||
register loc, np;
|
||||
|
||||
nproc = getuint((off_t)nl[SNPROC].n_value);
|
||||
xproc = (struct proc *)calloc(nproc, sizeof (struct proc));
|
||||
aproc = nl[SPROC].n_value;
|
||||
if (nproc < 0 || nproc > 10000) {
|
||||
fprintf(stderr, "number of procs is preposterous (%d)\n",
|
||||
nproc);
|
||||
return;
|
||||
}
|
||||
if (xproc == NULL) {
|
||||
fprintf(stderr, "can't allocate memory for proc table\n");
|
||||
return;
|
||||
}
|
||||
lseek(fc, (off_t)aproc, 0);
|
||||
read(fc, xproc, nproc * sizeof (struct proc));
|
||||
np = 0;
|
||||
for (pp=xproc; pp < &xproc[nproc]; pp++)
|
||||
if (pp->p_stat)
|
||||
np++;
|
||||
if (totflg) {
|
||||
printf("%3d/%3d processes\n", np, nproc);
|
||||
return;
|
||||
}
|
||||
printf("%d/%d processes\n", np, nproc);
|
||||
printf(" LOC S F PRI SIG UID SLP TIM CPU NI PGRP PID PPID ADDR SADDR DADDR SIZE WCHAN LINK SIGM\n");
|
||||
for (pp=xproc; pp<&xproc[nproc]; pp++) {
|
||||
if (pp->p_stat==0 && allflg==0)
|
||||
continue;
|
||||
printf("%08x", aproc + (pp - xproc)*sizeof (*pp));
|
||||
printf(" %2d", pp->p_stat);
|
||||
printf(" %7.1x", pp->p_flag);
|
||||
printf(" %3d", pp->p_pri);
|
||||
printf(" %8.1lx", pp->p_sig);
|
||||
printf(" %5u", pp->p_uid);
|
||||
printf(" %3d", pp->p_slptime);
|
||||
printf(" %3d", pp->p_time);
|
||||
printf(" %4d", pp->p_cpu&0377);
|
||||
printf(" %3d", pp->p_nice);
|
||||
printf(" %6d", pp->p_pgrp);
|
||||
printf(" %6d", pp->p_pid);
|
||||
printf(" %6d", pp->p_ppid);
|
||||
printf(" %8x", pp->p_addr);
|
||||
printf(" %8x", pp->p_saddr);
|
||||
printf(" %8x", pp->p_daddr);
|
||||
printf(" %6x", pp->p_dsize+pp->p_ssize);
|
||||
printf(" %8x", pp->p_wchan);
|
||||
printf(" %8x", pp->p_link);
|
||||
printf(" %8.1lx", pp->p_sigmask);
|
||||
printf("\n");
|
||||
}
|
||||
free(xproc);
|
||||
}
|
||||
|
||||
static int ttyspace = 64;
|
||||
static struct tty *tty;
|
||||
|
||||
dotty()
|
||||
{
|
||||
if ((tty = (struct tty *)malloc(ttyspace * sizeof(*tty))) == 0) {
|
||||
printf("pstat: out of memory\n");
|
||||
return;
|
||||
}
|
||||
dottytype("cn", SKL);
|
||||
}
|
||||
|
||||
dottytype(name, type)
|
||||
char *name;
|
||||
{
|
||||
register struct tty *tp;
|
||||
|
||||
printf("%s line\n", name);
|
||||
lseek(fc, (long)nl[type].n_value, 0);
|
||||
read(fc, tty, sizeof(struct tty));
|
||||
printf(" # RAW CAN OUT MODE ADDR DEL COL STATE PGRP\n");
|
||||
ttyprt(tty, 0);
|
||||
}
|
||||
|
||||
ttyprt(atp, line)
|
||||
struct tty *atp;
|
||||
{
|
||||
register struct tty *tp;
|
||||
|
||||
printf("%2d", line);
|
||||
tp = atp;
|
||||
|
||||
printf("%4d%4d", tp->t_rawq.c_cc, tp->t_canq.c_cc);
|
||||
printf("%4d %12.1lo %8x %4d %4d ", tp->t_outq.c_cc, tp->t_flags,
|
||||
tp->t_addr, tp->t_delct, tp->t_col);
|
||||
putf(tp->t_state&TS_TIMEOUT, 'T');
|
||||
putf(tp->t_state&TS_WOPEN, 'W');
|
||||
putf(tp->t_state&TS_ISOPEN, 'O');
|
||||
putf(tp->t_state&TS_FLUSH, 'F');
|
||||
putf(tp->t_state&TS_CARR_ON, 'C');
|
||||
putf(tp->t_state&TS_BUSY, 'B');
|
||||
putf(tp->t_state&TS_ASLEEP, 'A');
|
||||
putf(tp->t_state&TS_XCLUDE, 'X');
|
||||
putf(tp->t_state&TS_TTSTOP, 'S');
|
||||
putf(tp->t_state&TS_HUPCLS, 'H');
|
||||
putf(tp->t_state&TS_TBLOCK, 'b');
|
||||
putf(tp->t_state&TS_RCOLL, 'r');
|
||||
putf(tp->t_state&TS_WCOLL, 'w');
|
||||
putf(tp->t_state&TS_ASYNC, 'a');
|
||||
printf("%6d\n", tp->t_pgrp);
|
||||
}
|
||||
|
||||
dousr()
|
||||
{
|
||||
struct user U;
|
||||
long *ip;
|
||||
register i, j;
|
||||
|
||||
lseek(fm, ubase, 0);
|
||||
read(fm, &U, sizeof(U));
|
||||
printf("procp\t%p\n", U.u_procp);
|
||||
printf("frame\t%p\n", U.u_frame);
|
||||
printf("comm\t%s\n", U.u_comm);
|
||||
printf("arg\t%p %p %p %p %p %p\n", U.u_arg[0], U.u_arg[1],
|
||||
U.u_arg[2], U.u_arg[3], U.u_arg[4], U.u_arg[5]);
|
||||
printf("qsave\t");
|
||||
for (i = 0; i < sizeof (label_t) / sizeof (int); i++)
|
||||
printf("%p ", U.u_qsave.val[i]);
|
||||
printf("\n");
|
||||
printf("rval\t%p\n", U.u_rval);
|
||||
printf("error\t%d\n", U.u_error);
|
||||
printf("uids\t%d,%d,%d,%d,%d\n", U.u_uid, U.u_svuid, U.u_ruid,
|
||||
U.u_svgid, U.u_rgid);
|
||||
printf("groups");
|
||||
for (i = 0; (i < NGROUPS) && (U.u_groups[i] != NOGROUP); i++) {
|
||||
if (i%8 == 0) printf("\t");
|
||||
printf("%u ", U.u_groups[i]);
|
||||
if (i%8 == 7) printf("\n");
|
||||
}
|
||||
if (i%8) printf("\n");
|
||||
printf("tsize\t%.1x\n", U.u_tsize);
|
||||
printf("dsize\t%.1x\n", U.u_dsize);
|
||||
printf("ssize\t%.1x\n", U.u_ssize);
|
||||
printf("ssave\t");
|
||||
for (i = 0; i < sizeof (label_t) / sizeof (int); i++)
|
||||
printf("%.1x ", U.u_ssave.val[i]);
|
||||
printf("\n");
|
||||
printf("rsave\t");
|
||||
for (i = 0; i < sizeof (label_t) / sizeof (int); i++)
|
||||
printf("%.1x ", U.u_rsave.val[i]);
|
||||
printf("\n");
|
||||
printf("signal");
|
||||
for (i = 0; i < NSIG; i++) {
|
||||
if (i%8 == 0) printf("\t");
|
||||
printf("%.1x ", U.u_signal[i]);
|
||||
if (i%8 == 7) printf("\n");
|
||||
}
|
||||
if (i%8) printf("\n");
|
||||
printf("sigmask");
|
||||
for (i = 0; i < NSIG; i++) {
|
||||
if (i%8 == 0) printf("\t");
|
||||
printf("%.1lx ", U.u_sigmask[i]);
|
||||
if (i%8 == 7) printf("\n");
|
||||
}
|
||||
if (i%8) printf("\n");
|
||||
printf("sigonstack\t%.1lx\n", U.u_sigonstack);
|
||||
printf("sigintr\t%.1lx\n", U.u_sigintr);
|
||||
printf("oldmask\t%.1lx\n", U.u_oldmask);
|
||||
printf("code\t%08x\n", U.u_code);
|
||||
printf("psflags\t%d\n", U.u_psflags);
|
||||
printf("ss_base\t%.1x ss_size %.1x ss_flags %.1x\n",
|
||||
U.u_sigstk.ss_base, U.u_sigstk.ss_size, U.u_sigstk.ss_flags);
|
||||
printf("ofile");
|
||||
for (i = 0; i < NOFILE; i++)
|
||||
{
|
||||
if (i%8 == 0) printf("\t");
|
||||
printf("%.1x ", U.u_ofile[i]);
|
||||
if (i%8 == 7) printf("\n");
|
||||
}
|
||||
if (i%8) printf("\n");
|
||||
printf("pofile");
|
||||
for (i = 0; i < NOFILE; i++)
|
||||
{
|
||||
if (i%8 == 0) printf("\t");
|
||||
printf("%.1x ", U.u_pofile[i]);
|
||||
if (i%8 == 7) printf("\n");
|
||||
}
|
||||
if (i%8) printf("\n");
|
||||
printf("lastfile\t%d\n", U.u_lastfile);
|
||||
printf("cdir\t%.1x\n", U.u_cdir);
|
||||
printf("rdir\t%.1x\n", U.u_rdir);
|
||||
printf("ttyp\t%.1x\n", U.u_ttyp);
|
||||
printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd));
|
||||
printf("cmask\t%.1x\n", U.u_cmask);
|
||||
printf("ru\t");
|
||||
ip = (long *)&U.u_ru;
|
||||
for (i = 0; i < sizeof (U.u_ru) / sizeof (long); i++)
|
||||
printf("%ld ", ip[i]);
|
||||
printf("\n");
|
||||
printf("cru\t");
|
||||
ip = (long *)&U.u_cru;
|
||||
for (i = 0; i < sizeof (U.u_cru) / sizeof (long); i++)
|
||||
printf("%ld ", ip[i]);
|
||||
printf("\n");
|
||||
printf("timer\t%ld %ld %ld %ld\n", U.u_timer[0].it_interval,
|
||||
U.u_timer[0].it_value, U.u_timer[1].it_interval,
|
||||
U.u_timer[1].it_value);
|
||||
printf("start\t%08x\n", U.u_start);
|
||||
printf("prof\t%.1x %u %u %u\n", U.u_prof.pr_base, U.u_prof.pr_size,
|
||||
U.u_prof.pr_off, U.u_prof.pr_scale);
|
||||
printf("rlimit cur\t");
|
||||
for (i = 0; i < RLIM_NLIMITS; i++)
|
||||
{
|
||||
if (U.u_rlimit[i].rlim_cur == RLIM_INFINITY)
|
||||
printf("infinite ");
|
||||
else
|
||||
printf("%ld ", U.u_rlimit[i].rlim_cur);
|
||||
}
|
||||
printf("\n");
|
||||
printf("rlimit max\t");
|
||||
for (i = 0; i < RLIM_NLIMITS; i++)
|
||||
{
|
||||
if (U.u_rlimit[i].rlim_max == RLIM_INFINITY)
|
||||
printf("infinite ");
|
||||
else
|
||||
printf("%ld ", U.u_rlimit[i].rlim_max);
|
||||
}
|
||||
printf("\n");
|
||||
printf("ncache\t%ld %u %d,%d\n", U.u_ncache.nc_prevoffset,
|
||||
U.u_ncache.nc_inumber, major(U.u_ncache.nc_dev),
|
||||
minor(U.u_ncache.nc_dev));
|
||||
}
|
||||
|
||||
oatoi(s)
|
||||
char *s;
|
||||
{
|
||||
register v;
|
||||
|
||||
v = 0;
|
||||
while (*s)
|
||||
v = (v<<3) + *s++ - '0';
|
||||
return(v);
|
||||
}
|
||||
|
||||
dofile()
|
||||
{
|
||||
struct file *xfile;
|
||||
register struct file *fp;
|
||||
register nf;
|
||||
u_int loc, afile;
|
||||
static char *dtypes[] = { "???", "inode", "socket", "pipe" };
|
||||
|
||||
nf = 0;
|
||||
xfile = (struct file *)calloc(NFILE, sizeof (struct file));
|
||||
if (xfile == NULL) {
|
||||
fprintf(stderr, "can't allocate memory for file table\n");
|
||||
return;
|
||||
}
|
||||
afile = nl[SFIL].n_value;
|
||||
lseek(fc, (off_t)afile, 0);
|
||||
read(fc, xfile, NFILE * sizeof (struct file));
|
||||
for (fp=xfile; fp < &xfile[NFILE]; fp++)
|
||||
if (fp->f_count)
|
||||
nf++;
|
||||
if (totflg) {
|
||||
printf("%3d/%3d files\n", nf, NFILE);
|
||||
return;
|
||||
}
|
||||
printf("%d/%d open files\n", nf, NFILE);
|
||||
printf(" LOC TYPE FLG CNT MSG DATA OFFSET\n");
|
||||
loc = afile;
|
||||
for (fp=xfile; fp < &xfile[NFILE]; fp++, loc += sizeof (*fp))
|
||||
{
|
||||
if (fp->f_count==0)
|
||||
continue;
|
||||
printf("%08x ", loc);
|
||||
if (fp->f_type <= DTYPE_PIPE)
|
||||
printf("%-8.8s", dtypes[fp->f_type]);
|
||||
else
|
||||
printf("8d", fp->f_type);
|
||||
putf((long)fp->f_flag&FREAD, 'R');
|
||||
putf((long)fp->f_flag&FWRITE, 'W');
|
||||
putf((long)fp->f_flag&FAPPEND, 'A');
|
||||
putf((long)fp->f_flag&FSHLOCK, 'S');
|
||||
putf((long)fp->f_flag&FEXLOCK, 'X');
|
||||
putf((long)fp->f_flag&FASYNC, 'I');
|
||||
putf((long)fp->f_flag&FNONBLOCK, 'n');
|
||||
putf((long)fp->f_flag&FMARK, 'm');
|
||||
putf((long)fp->f_flag&FDEFER, 'd');
|
||||
printf(" %3d", fp->f_count);
|
||||
printf(" %3d", fp->f_msgcount);
|
||||
printf(" %08x", fp->f_data);
|
||||
if (fp->f_offset < 0)
|
||||
printf(" 0x%lx\n", fp->f_offset);
|
||||
else
|
||||
printf(" %ld\n", fp->f_offset);
|
||||
}
|
||||
free(xfile);
|
||||
}
|
||||
|
||||
doswap()
|
||||
{
|
||||
u_int nswap, used;
|
||||
int i, num;
|
||||
struct map smap;
|
||||
struct mapent *swp;
|
||||
|
||||
nswap = getuint((off_t)nl[SNSWAP].n_value);
|
||||
|
||||
lseek(fc, (off_t)nl[SWAPMAP].n_value, 0);
|
||||
read(fc, &smap, sizeof (smap));
|
||||
num = (smap.m_limit - smap.m_map);
|
||||
swp = (struct mapent *)calloc(num, sizeof (*swp));
|
||||
lseek(fc, (off_t)smap.m_map, 0);
|
||||
read(fc, swp, num * sizeof (*swp));
|
||||
for (used = 0, i = 0; swp[i].m_size; i++)
|
||||
used += swp[i].m_size;
|
||||
printf("%d/%d swapmap entries\n", i, num);
|
||||
printf("%u kbytes swap used, %u kbytes free\n", nswap - used, used);
|
||||
}
|
||||
Reference in New Issue
Block a user