ps - show process status - iiasa version (jek)
originally from harvard and/or CULC
multiple flags can occur in one argument
dashes are optional but are needed to delimit lists of things
multiple lists are present(???)
flags that imply other arguments read the following arguments
until the end of the list or until an argument starts with dash
certain flags read exactly one argument
initialization (i flag) should be done for:
parameters here must change to indicate:
new tty devices, max tty lines, tty letter changes
this program should be changed if:
proc structure makes this obsolete
recompilation should occur if:
kernel structures and or paramters (nproc etc.) change
any above changes of course
a - show all processes that have pgrps except shells
b - show background (not detached)
c - show child times instead of process times
d - show detached processes inherited by init
e - show the environment with the args
f - show foreground jobs, connected to tty
g - show processes in given pgrps
i - perform initialization (implies 'n')
l - print long format. includes most good stuff
m - specify different memory file (file is next arg)
p - show only processes whose id's are in list (following args)
r - repeat indefinitely (number of r's = seconds or r#)
s - show stopped processes
t - show only processes associated with ttys in list (following)
u - show only processes (or ancestors of) for users in list
v - be verbose - show the most information
w - wide format, show entire argument list (up to 512 chars)
x - show unattached processes - no pgrp. a+x gives shells also
A - show ALL information possible
F - go fast, avoid swap space.
U - use different UNIX file (next arg)
W - print wait channels in hex
#define INTPPG (NBPG/sizeof(int))
#define Usrptmap ((struct pte *)info.kaddr[ausrptmap])
#define usrpt ((struct pte *)info.kaddr[ausrpt])
#define cswitch ((struct cdevsw *)info.kaddr[acdevsw])
struct proc
*proc
, *kproc
;
struct text
*text
, *ktext
;
int nproc
, ntext
, hz
, nbuf
, ninode
, nfile
, nswbuf
;
char upages
[UPAGES
][NBPG
];
int pad1
; /* supposedly to aviod hardware problem reading /dev/mem */
struct pte pagetable
[UPAGES
+ MAXARGPG
]; /* for users page table */
int pad2
; /* supposedly to aviod hardware problem reading /dev/mem */
#define MSPID 2 /* max system pid, not to considered BUSY */
#define MAXUSERS 256 /* total different users */
#define UNAMELENGTH 8 /* length of a user name */
#define NSPEC 15 /* number of specified things (proc, user, tty */
/* definitions to reuse uninteresting proc table entries for linked lists */
struct procinfo
{ /* structure to use for */
char *pi_cmd
; /* attaching a time */
long pi_time
; /* and an arg string to a proc */
#define p_next p_link /* pointer to next proc in global list */
#define p_bro p_rlink /* next process with same parent */
#define p_son p_xlink /* first child of this process */
#define pinfo(p) (*((struct procinfo **)&p->p_sig))
#define procsize(p) ((p)->p_tsize + (p)->p_dsize + (p)->p_ssize)
#define ABS(x) ((int)(x) & ~0x80000000) /* clear top bit - type int */
#define msize(x) (x >> (KSHIFT-PGSHIFT))
#define USERPAGE 0 /* flag for pread - read user page */
#define TOPMEM 1 /* flag for pread - read top of mem */
int mypid
; /* pid of this process */
char Aflag
, aflag
, Bflag
, bflag
, cflag
, dflag
, eflag
, fflag
, Fflag
;
char Gflag
, iflag
, lflag
, mflag
, nflag
, rflag
, Sflag
, sflag
, Tflag
;
char Uflag
, uflag
, vflag
, wflag
, xflag
, nxflag
, Wflag
, zflag
;
int select
; /* flag indicating process selection */
int ntotal
, nbusy
, nloaded
, nswapped
;
int ktotal
, kbusy
, kloaded
, kswapped
;
/* specified users, ttys, pids, pgrps */
union numptr pids
[NSPEC
], *ppids
= pids
; /* specified process ids */
union numptr grps
[NSPEC
], *pgrps
= grps
; /* specified groups */
union numptr uids
[NSPEC
], *puids
= uids
; /* specified user ids */
union ttyptr ttys
[NSPEC
], *pttys
= ttys
; /* specified ttys */
char *memf
= "/dev/mem"; /* default memory file */
int mem
; /* memory file descriptor */
char *kmemf
= "/dev/kmem"; /* virtual memory file */
int kmem
; /* virtual memory file descriptor */
char *symf
= "/vmunix"; /* default symbol file */
char *swapf
= "/dev/swap"; /* default swap file */
int swap
; /* swap area file descriptor */
char *infof
= "/etc/spsinfo"; /* default info save file */
int infofd
; /* info file descriptor */
/* variables read from the kernel */
struct nlist namelist
[] = {
/* this structure is read from info file or initialized (iflag) */
caddr_t kaddr
[MAXSYMBOLS
]; /* useful kernel addresses */
char unames
[MAXUSERS
][UNAMELENGTH
]; /* user names */
struct tty
*l_addr
; /* address of ttystruct */
unsigned l_pgrp
; /* process group */
char l_name
[2]; /* name */
dev_t l_dev
; /* device number */
int swapdev
; /* major, minor of swap device */
int swplo
; /* unix swap disk offset */
int nswap
; /* unix swap space size */
struct ttyline notty
= {0, 0, {"- "}};
/* flags for once only activities (once per repeat) */
char *getcore(), *store(), *waitingfor(), *getcmd(), *strcat(), *brk();
if ((myuid
= getuid()) == 0)
for (ap
= &argv
[1]; --argc
; ap
++) {
case 'A': /* EVERYTHING */
case 'a': /* all procs attached to ttys */
bflag
++; /* include background */
fflag
++; /* include foreground */
dflag
++; /* include detached */
aflag
++; /* include shells */
case 'b': /* all background processes */
case 'B': /* all busy processes */
case 'd': /* detached processes */
case 'f': /* foreground only */
case 'F': /* go fast, don't touch swap */
case 'G': /* print pgrp */
case 'g': /* specify process gourp */
if (pgrps
>= &grps
[NSPEC
])
prexit("%a: too many groups\n");
(pgrps
++)->nm_int
= atoi(*ap
);
(pgrps
++)->nm_int
= getpgrp();
case 'i': /* initialize info file */
if (myuid
!= 0) /* must be super user */
case 'l': /* long output */
case 'm': /* use designated memory file */
if (myuid
!= 0) /* must be super user */
if (argc
-- < 2 || **++ap
== '-')
prexit("%a: missing memory file\n");
case 'p': /* only designated processes */
if (ppids
>= &pids
[NSPEC
])
prexit("%a: too many pids\n");
(ppids
++)->nm_int
= atoi(*ap
);
case 'r': /* repeat every <number> seconds */
for (i
= 0; *cp
>= '0' && *cp
<= '9'; cp
++)
case 'U': /* use designated symbol file */
if (argc
-- < 2 || **++ap
== '-')
prexit("%a: missing symbol file\n");
case 't': /* on designated tty(s) */
if (pttys
>= &ttys
[NSPEC
])
prexit("%a: too many ttys\n");
if ( (pttys
->ty_ptr
= ttyname(2)) == 0)
prexit("%a: unknown tty\n");
else if (strcmp("/dev/console", pttys
->ty_ptr
) == 0)
(pttys
++)->ty_ptr
= "co";
case 'u': /* specific user name */
if (puids
>= &uids
[NSPEC
])
prexit("%a: too many users\n");
(puids
++)->nm_int
= myuid
;
case 'v': /* most verbose output */
case 'w': /* wide form (all arguments) */
case 'x': /* include un-owned procs */
case 'z': /* include only zombies */
prexit("%a: unknown switch: %c\n", *--cp
);
/* these lengths are kludgely tuned to make things not exceed 79 columns */
if ((mem
= open(memf
, 0)) < 0)
prexit("%a: cannot read system memory: %s\n", memf
);
if ((kmem
= open(kmemf
, 0)) < 0)
prexit("%a: cannot read system virtural memory: %s\n", kmemf
);
if (!Fflag
&& (swap
= open(swapf
, 0)) <0)
prexit("%a: cannot read swap device: %s\n", swapf
);
if ((i
= open(infof
, 0)) < 0)
prexit("%a: cannot open info file\n");
else if (read(i
, &info
, sizeof info
) != sizeof info
)
prexit("%a: cannot read info file\n");
if ((i
= open(symf
, 0)) < 0)
prexit("%a: can't read symbol file\n");
for (np
= namelist
; np
< &namelist
[MAXSYMBOLS
]; np
++)
fprintf(stderr
, "%a: can't find symbol: %s\n",
if (namelist
[0].n_value
== -1)
prexit("%a: cannot read symbol file: %s\n", symf
);
for (i
= 0; i
< MAXSYMBOLS
; i
++)
info
.kaddr
[i
] = (caddr_t
)namelist
[i
].n_value
;
info
.kaddr
[aetext
] = (caddr_t
)( ((unsigned)info
.kaddr
[aetext
] + 63) & ~63);
if ((infofd
= creat(infof
, 0600)) < 0)
prexit("%a: cannot create info file\n");
if ((i
= write(infofd
, &info
, sizeof info
)) != sizeof info
) {
prexit("%a: cannot write info file: %d\n", i
);
lseek(kmem
, (long)info
.kaddr
[aswapdev
], 0);
read(kmem
, &swapdev
, sizeof(swapdev
) );
lseek(kmem
, (long)info
.kaddr
[aswplo
], 0);
read(kmem
, &swplo
, sizeof(swplo
) );
lseek(kmem
, (long)info
.kaddr
[answap
], 0);
read(kmem
, &nswap
, sizeof(nswap
) );
lseek(kmem
, (long)info
.kaddr
[anproc
], 0);
read(kmem
, &nproc
, sizeof(nproc
) );
lseek(kmem
, (long)info
.kaddr
[antext
], 0);
read(kmem
, &ntext
, sizeof(ntext
) );
lseek(kmem
, (long)info
.kaddr
[anbuf
], 0);
read(kmem
, &nbuf
, sizeof(nbuf
) );
lseek(kmem
, (long)info
.kaddr
[abuf
], 0);
read(kmem
, &buf
, sizeof(buf
) );
lseek(kmem
, (long)info
.kaddr
[answbuf
], 0);
read(kmem
, &nswbuf
, sizeof(nswbuf
) );
lseek(kmem
, (long)info
.kaddr
[aswbuf
], 0);
read(kmem
, &swbuf
, sizeof(swbuf
) );
lseek(kmem
, (long)info
.kaddr
[aninode
], 0);
read(kmem
, &ninode
, sizeof(ninode
) );
lseek(kmem
, (long)info
.kaddr
[ainode
], 0);
read(kmem
, &inode
, sizeof(inode
) );
lseek(kmem
, (long)info
.kaddr
[ahz
], 0);
read(kmem
, &hz
, sizeof(hz
) );
lseek(kmem
, (long)info
.kaddr
[aproc
], 0);
read(kmem
, &kproc
, sizeof(kproc
));
lseek(kmem
, (long)info
.kaddr
[atext
], 0);
read(kmem
, &ktext
, sizeof(ktext
));
proc
= (struct proc
*)getcore(nproc
* sizeof(struct proc
));
text
= (struct text
*)getcore(ntext
* sizeof(struct text
));
if (puids
!= &uids
[0] && uids
[0].nm_int
!= myuid
)
(puids
++)->nm_int
= myuid
;
heading
= 0; /* reset heading flag (for repeat) */
core
= coreinit
= 0; /* reset core flag (for repeat) */
lseek(kmem
, (long)kproc
, 0);
read(kmem
, proc
, nproc
* sizeof(struct proc
));
lseek(kmem
, (long)ktext
, 0);
read(kmem
, text
, ntext
* sizeof(struct text
));
printf("%d processes (%dkb), %d busy (%dkb), %d loaded (%dkb)\n",
ntotal
, (ctob(ktotal
) + 1023) / 1024,
nbusy
, (ctob(kbusy
) + 1023) / 1024,
nloaded
, (ctob(kloaded
) + 1023) / 1024);
} while (rflag
&& sleep(rflag
) == 0);
/* read the passwd file and fill in the user name arrays */
register struct passwd
*pw
;
struct passwd
*getpwent();
while((pw
= getpwent()) != 0) {
if(info
.unames
[pw
->pw_uid
][0] == '\0')
strcpyn(info
.unames
[pw
->pw_uid
], pw
->pw_name
, UNAMELENGTH
);
/* check for specified user names */
register union numptr
*ip
;
for (ip
= uids
; ip
< puids
; ip
++) {
for (i
= 0; i
< MAXUSERS
; i
++)
if (equalu(ip
->nm_ptr
, info
.unames
[i
]))
prexit("%a: unknown user: %s\n", ip
->nm_ptr
);
/* compare a fixed length user name */
if (!*u2
++ || ++i
== UNAMELENGTH
)
* Initialize the tty part of the info structure
register struct ttyline
*lp
= info
.ttyline
;
if ((fd
= open("/dev", 0)) < 0)
prexit("%a: can't open /dev\n");
while (read(fd
, (char *)&dir
, sizeof(dir
)) == sizeof(dir
)) {
strncmp("tty", dir
.d_name
, 3) != 0 &&
strcmp("console", dir
.d_name
) != 0)
if (dir
.d_name
[sizeof("tty") - 1] == 'C')
if (lp
>= &info
.ttyline
[MAXTTYS
])
prexit("%a: too many ttys in /dev\n");
if (dir
.d_name
[0] == 'c') {
lp
->l_name
[0] = dir
.d_name
[3];
lp
->l_name
[1] = dir
.d_name
[4];
lp
->l_dev
= sbuf
.st_rdev
;
lseek(kmem
, (long)&cswitch
[major(sbuf
.st_rdev
)].d_ttys
, 0);
read(kmem
, (char *)&lp
->l_addr
, sizeof(lp
->l_addr
));
lp
->l_addr
+= minor(sbuf
.st_rdev
);
register struct ttyline
*lp
;
for (lp
= info
.ttyline
; lp
->l_name
[0]; lp
++) {
lseek(kmem
, (long)lp
->l_addr
, 0);
if (read(kmem
, &tty
, sizeof tty
) != sizeof tty
)
prexit("%a: read error in kmem\n");
printf("tty%-.2s: dev:%2d,%2d addr:%6x, rawq:%4d, canq:%d, outq:%4d, pgrp:%5d\n",
lp
->l_name
, major(lp
->l_dev
), minor(lp
->l_dev
),
ABS(lp
->l_addr
), tty
.t_rawq
.c_cc
,
tty
.t_canq
.c_cc
, tty
.t_outq
.c_cc
,
/* now fix up specified ttys */
for (tp
= &ttys
[0]; tp
< pttys
; tp
++) {
for (lp
= info
.ttyline
; lp
->l_name
[0]; lp
++)
if (strcmpn(tp
->ty_ptr
, lp
->l_name
, 2) == 0) {
prexit("%a: unknown tty name: %c\n", tp
->ty_ptr
);
* Determine which procs are needed for the printout
* and add these to a list of needed processes (plist)
register struct proc
*p
, *pp
;
register struct text
*tp
;
nswapped
= ntotal
= nbusy
= nloaded
= 0;
kswapped
= ktotal
= kbusy
= kloaded
= 0;
for (tp
= text
; tp
< text
+ ntext
; tp
++)
for (p
= proc
; p
< proc
+ nproc
; p
++) {
p
->p_textp
= &text
[p
->p_textp
- ktext
];
p
->p_pptr
= &proc
[p
->p_pptr
- kproc
];
if (p
->p_pptr
< proc
|| p
->p_pptr
>= &proc
[nproc
]) {
fprintf(stderr
, "proc %d bad pptr\n", p
->p_pid
);
for (p
= &proc
[0]; p
< &proc
[nproc
]; p
++) {
if ((tp
= p
->p_textp
) && tp
->x_count
) {
p
->p_stat
== SSLEEP
&& (p
->p_pri
< PZERO
&& p
->p_pid
> MSPID
)) {
if ((tp
= p
->p_textp
) && tp
->x_ccount
) {
if (zflag
&& p
->p_stat
== SZOMB
)
if (sflag
&& p
->p_stat
== SSTOP
)
if (select
== 0 && mypid
&& p
->p_pid
== mypid
)
if (dflag
&& p
->p_pgrp
!= 0 && (p
->p_flag
& SDETACH
) != 0)
if (aflag
&& xflag
&& p
->p_pgrp
!= 0 && (p
->p_flag
& SDETACH
) == 0 &&
register union numptr
*ip
;
for (pp
= p
; pp
> &proc
[1]; pp
= pp
->p_pptr
)
for (ip
= uids
; ip
< puids
; ip
++)
if ((pp
->p_uid
& 0377) == ip
->nm_int
){
register union numptr
*ip
;
for (pp
= p
; pp
> &proc
[1]; pp
= pp
->p_pptr
)
for (ip
= grps
; ip
< pgrps
; ip
++)
if (pp
->p_pgrp
== ip
->nm_int
) {
register union numptr
*ip
;
for (ip
= pids
; ip
< ppids
; ip
++)
if (ip
->nm_int
== p
->p_pid
) {
if (select
&& pttys
== ttys
&& !fflag
&& !bflag
&& !ok
)
static struct procinfo fakep
= {"--no upage--", ¬ty
, 0};
if (pttys
!= ttys
&& p
->p_pgrp
!= 0) {
for (ip
= ttys
; ip
< pttys
; ip
++)
if (p
->p_pgrp
&& p
->p_pgrp
== ip
->ty_line
->l_pgrp
||
p
->p_wchan
>= (char *)ip
->ty_line
->l_addr
&&
p
->p_wchan
< (char *)ip
->ty_line
->l_addr
+
u
.u_ttyd
== ip
->ty_line
->l_dev
) {
for (lp
= info
.ttyline
; lp
->l_name
[0] != 0; lp
++)
if (lp
->l_dev
== u
.u_ttyd
)
else if (p
->p_pptr
!= &proc
[1]) {
if (fflag
&& p
->p_pgrp
== lp
->l_pgrp
)
if (bflag
&& p
->p_pgrp
!= lp
->l_pgrp
&&
(p
->p_flag
& SDETACH
) == 0 &&
pinfo(p
) = (struct procinfo
*)getcore(sizeof (struct procinfo
));
pinfo(p
)->pi_time
= u
.u_vm
.vm_utime
+ u
.u_vm
.vm_stime
;
pinfo(p
)->pi_cmd
= getcmd(p
);
/* we have a needed proc! */
* mktree - sort the needed processes by subtree and at the top by user
register struct proc
*p
, *pp
, *lp
;
for (p
= plist
; p
; p
= p
->p_next
) { /* for all needed processes */
if (p
->p_pptr
> &proc
[1]) {
for (pp
= plist
; pp
; pp
= pp
->p_next
)
if (pp
== p
->p_pptr
) { /* if my parent */
if (lp
= pp
->p_son
) { /* if siblings */
for (op
= 0; lp
&& lp
->p_pid
<
p
->p_bro
= lp
; /* here if first or only */
if (pp
) /* if we found the parent */
/* we have a top level process, sort into top level list */
for (pp
= (lp
= &proot
)->p_bro
; pp
; pp
= (lp
= pp
)->p_bro
)
if ((p
->p_uid
& 0377) < (pp
->p_uid
& 0377) ||
(p
->p_uid
& 0377) == (pp
->p_uid
& 0377) &&
* Pretty print the output according to the switches.
static char *statnames
[] = {"Unk ", "Wait", "Wait", "Run ",
if (vflag
) printf(" Flgs Nice Pri ");
printf("Memory-kb Time Wait? ");
printf("Address Proc. Clock Alarm ");
printf("Proc# Command\n");
printf("%.2s%c", pinfo(p
)->pi_tty
->l_name
,
p
->p_flag
& SDETACH
? '_' :
p
->p_pgrp
== pinfo(p
)->pi_tty
->l_pgrp
? '.' :
lastuid
= p
->p_uid
& 0377;
cp
= info
.unames
[lastuid
];
printf("user%-4.4d ", lastuid
);
if ((p
->p_uid
& 0377) != lastuid
) { /* setuid process! */
lastuid
= p
->p_uid
& 0377;
cp
= info
.unames
[lastuid
];
printf("%-*.*s", md
, md
, cp
);
cp
= statnames
[p
->p_stat
];
for (cp1
= stat
; *cp1
= *cp
; cp1
++, cp
++)
if (*cp
>= 'a' && *cp
<= 'z')
if (p
->p_flag
& SSYS
) *cp
++ = 'U';
if (p
->p_flag
&SLOCK
) *cp
++ = 'L';
if (p
->p_flag
&STRC
) *cp
++ = 'T';
if (p
->p_flag
&SWTED
) *cp
++ = 'W';
if (p
->p_flag
&SSWAP
) *cp
++ = 'S';
while(cp
< &stat
[5]) *cp
++ = ' ';
printf("%4d", p
->p_nice
- NZERO
);
printf("%4d ", p
->p_pri
);
if (p
->p_stat
!= SZOMB
) {
printf("%4d", msize(procsize(p
)) );
printf("+%4d ", msize(p
->p_textp
->x_size
));
prcpu(pinfo(p
)->pi_time
);
if (p
->p_stat
!= SZOMB
&& p
->p_stat
!= SRUN
&& p
->p_stat
!= SSTOP
)
if (!Wflag
&& (cp
= waitingfor(p
)))
else printf("%6x ", ABS((int)p
->p_wchan
));
printf("%6x %6x %6d%6d ", p
->p_addr
,
(p
- proc
) * sizeof (struct proc
) + info
.kaddr
[aproc
],
printf("%5x ", procsize(p
) );
printf("%5D ", p
->p_pgrp
);
printf("%5D ", p
->p_pid
);
printf("%s\n", pinfo(p
)->pi_cmd
);
printf("%-.*s\n", arglength
, pinfo(p
)->pi_cmd
);
else if (time
< (long)hz
* 60 * 10) /* less than 10 minutes */
(int)(time
% hz
/ (hz
/ 10)));
else if (time
< (long)hz
* 60 * 60 * 10)/* less than 10 hours */
(int)((time
+ (hz
* 60) / 2) / (hz
* 60)));
i
= (time
+ ((long)hz
* 60 * 60) / 2) /
/* Determine what a process is waiting for and describe it. */
register struct ttyline
*lp
;
if (w
>= (char *)kproc
&& w
< (char *)(kproc
+ nproc
))
if (w
>= (char *)swbuf
&& w
< (char *)(swbuf
+ nswbuf
))
if (w
== info
.kaddr
[arswbuf
])
if (w
>= (char *)buf
&& w
< (char *)(buf
+ nbuf
))
if (w
>= info
.kaddr
[afile
] && w
< info
.kaddr
[afile
] + sizeof(struct file
) * nfile
)
if (w
>= (char *)inode
&& w
< (char *)(inode
+ ninode
))
switch((w
- (char *)inode
) % sizeof(struct inode
)) {
case (int)&((struct inode
*)0)->i_un
.i_group
.g_datq
:
if (w
== info
.kaddr
[achtbuf
])
if (w
== info
.kaddr
[ahpbuf
])
if (w
== info
.kaddr
[ark7
])
if (w
== info
.kaddr
[arhtbuf
])
if (w
== info
.kaddr
[alpdt
])
if (w
== info
.kaddr
[albolt
])
if (w
== info
.kaddr
[arunin
])
if (w
== info
.kaddr
[arunout
])
if (w
== info
.kaddr
[atout
])
if (w
== info
.kaddr
[aipc
])
if (w
== info
.kaddr
[abfreeli
])
if (w
== info
.kaddr
[amaplock
])
if (w
== info
.kaddr
[achrfclist
])
for (lp
= info
.ttyline
; lp
->l_name
[0]; lp
++)
if (w
>= (char *)lp
->l_addr
&& w
< (char *)lp
->l_addr
+ sizeof (struct tty
)) {
#define TTY0 ((struct tty *)0)
switch(w
- (char *)lp
->l_addr
) {
case (int)&TTY0
->t_state
:
register struct proc
*mproc
;
struct pte
*pteaddr
, apte
;
size
= Sflag
? ctob(UPAGES
) : sizeof (struct user
);
if ((mproc
->p_flag
& SLOAD
) == 0) {
lseek(swap
, (long)ctob(mproc
->p_swaddr
), 0);
if (read(swap
, (char *)&user
.user
, size
) != size
) {
fprintf(stderr
, "%a: cant read u for pid %d from %s\n",
pteaddr
= &Usrptmap
[btokmx(mproc
->p_p0br
) + mproc
->p_szpt
- 1];
lseek(kmem
, (long)(mflag
? ABS(pteaddr
) : (int)pteaddr
), 0);
if (read(kmem
, (char *)&apte
, sizeof(apte
)) != sizeof(apte
)) {
printf("%a: cant read indir pte to get u for pid %d from %s\n",
(ctob(apte
.pg_pfnum
+1) - (UPAGES
+MAXARGPG
) * sizeof (struct pte
)),
if (read(mem
, (char *)pagetable
, sizeof(pagetable
)) != sizeof(pagetable
)) {
printf("%a: cant read page table for u of pid %d from %s\n",
ncl
= (size
+ NBPG
*CLSIZE
- 1) / (NBPG
*CLSIZE
);
lseek(mem
, (long)ctob(pagetable
[MAXARGPG
+i
].pg_pfnum
), 0);
if (read(mem
, user
.upages
[i
], CLSIZE
*NBPG
) != CLSIZE
*NBPG
) {
printf("%a: cant read page %d of u of pid %d from %s\n",
pagetable
[MAXARGPG
+i
].pg_pfnum
, mproc
->p_pid
, memf
);
char argbuf
[MAXARGPG
* NBPG
], *argptr
;
if ((p
->p_flag
&SLOAD
) == 0 && Fflag
)
return p
->p_pid
== 0 ? "UNIX Swapper" :
p
->p_pid
== 2 ? "UNIX Pager" : "UNIX";
for (i
= 0; i
< MAXARGPG
; i
++) {
argptr
= &argbuf
[(MAXARGPG
- 1 - i
) * NBPG
];
apte
= pagetable
[MAXARGPG
- 1 - i
];
if ((p
->p_flag
& SLOAD
) && apte
.pg_fod
== 0 && apte
.pg_pfnum
) {
lseek(mem
, (long)ctob(apte
.pg_pfnum
), 0);
if (read(mem
, argptr
, NBPG
) != NBPG
)
return "---Mem read error (args)---";
lseek(swap
, (long)ctob(u
.u_smap
.dm_map
[0] + DMMIN
- 1 - i
), 0);
if (read(swap
, argptr
, NBPG
) != NBPG
)
return "---Swap read error (args)---";
/* Here block of stack is at argptr */
ip
= (int *)&argptr
[NBPG
];
while (ip
> (int *)argptr
&& *--ip
!= 0)
if (ip
> (int *)argptr
|| *ip
== 0)
strncpy(&argbuf
[1], u
.u_comm
, sizeof(u
.u_comm
));
for (cp1
= cp
; cp1
< &argbuf
[MAXARGPG
*NBPG
]; cp1
++) {
else if (cc
< ' ' || cc
== 0177) {
} else if (!eflag
&& cc
== '=') {
while (cp1
> cp
&& *--cp1
!= ' ')
if (!wflag
&& &cp
[arglength
] < (char *)&argbuf
[MAXARGPG
*NBPG
- 1])
* Store a string in core for later use.
register char *src
, *dst
, *svdst
;
svdst
= getcore(src
- cp
);
* Allocate and return a pointer to the asked for amount of core
brk(topmem
); /* after repeat!! */
incr
= cnt
> 4096 ? cnt
: 4096;
prexit("%a: out of memory!\n");
#include "chunix/chsys.h"
register struct ttyline
*lp
;
register struct connection
**cnp
;
struct connection
*Chconntab
[CHNCONNS
];
lseek(kmem
, (long)info
.kaddr
[aChconntab
], 0);
read(kmem
, (char *)Chconntab
, sizeof(Chconntab
));
for (i
= 0, cnp
= Chconntab
; cnp
< &Chconntab
[CHNCONNS
]; i
++, cnp
++) {
lseek(kmem
, (long)*cnp
, 0);
read(kmem
, (char *)&conn
, sizeof(conn
));
if ((conn
.cn_flags
& CHTTY
) == 0)
lseek(kmem
, (long)conn
.cn_ttyp
, 0);
read(kmem
, (char *)&tty
, sizeof(tty
));
if (lp
>= &info
.ttyline
[MAXTTYS
])
prexit("%a: too many ttys\n");
lp
->l_addr
= conn
.cn_ttyp
;
lp
->l_name
[1] = i
< 10 ? '0' + i
:
i
- 10 <= 'z' - 'a' ? i
- 10 + 'a' :
i
- 10 - ('z' - 'a') + 'A';
printf("tty%-.2s: dev:%2d,%2d addr:%6x, rawq:%4d, canq:%d, outq:%4d, pgrp:%5d\n",
lp
->l_name
, major(lp
->l_dev
), minor(lp
->l_dev
),
ABS(lp
->l_addr
), tty
.t_rawq
.c_cc
,
tty
.t_canq
.c_cc
, tty
.t_outq
.c_cc
,