🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: mod.computers.masscomp
1 messages
1 total messages Started by masscomp Sat, 14 Jun 1986 21:45
cinfo demo program
#15
Author: masscomp
Date: Sat, 14 Jun 1986 21:45
251 lines
6625 bytes

Here is my attempt to use cinfo. It is not perfect, but perhaps
some of you can fix the problems that it has.
Use 
cc -O cinfo.c -o cinfo -lm
to compile.
==============================================================
#include <stdio.h>
#include <nlist.h>
#include <pwd.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/pte.h>
#include <sys/dir.h>
#undef DIRSIZ
#define DIRSIZ 14
#include <sys/minmax.h>
#include <sys/cmap.h>
#include <sys/text.h>
#include <sys/cinfo.h>
#include <sys/user.h>
#include <sys/proc.h>

#define MAX_CMAP 2048
#define MAX_PROC 300
#define MAX_TEXT 100
#define KMEM "/dev/kmem"
#define MEM  "/dev/mem"
#define VMUNIX "/unix"

static char rcsid[]= "$Header: cinfo.c,v 1.1 86/06/14 16:40:07 sob Exp $";

extern int errno;
extern char * sys_errlist[];
struct nlist nlst[] = {
    { "_avenrun" },
#define X_AVENRUN	0
    { "_ccpu" },
#define X_CCPU		1
    { "_mpid" },
#define X_MPID          2
    { "_freemem" },
#define X_FREEMEM	3
    { 0 },
};

/* process state names for the "STATE" column of the display */

char *state_abbrev[] = {
    "", "sleep", "run", "WAIT", "idle", "", "","", "zomb","", "",
    "", "", "", "", "", "tired", "","", "","", "",
};

struct proc proc_v[MAX_PROC];
struct text text_v[MAX_TEXT];
struct cmap cmap_v[MAX_CMAP];
struct user u;

struct cu_des cu_des;
short proc_count;
short text_count;
short cmap_count;
int status,mem,kmem;
char * username();
/* this program attempts to do something like ps on a Masscomp */
/* it seems to work fine on a 5600/5700 but stil has problems on a 5500 */
static char * copyright = "Copyright 1986 Stan Barber\n";
/* This program may be freely distributed in source or binary as long as no
 * sale is made of this program in any form.
 * Stan Barber assumes no liability for the use of this program good or bad.
 * Stan Barber makes no guarentees relating to the correctness of this program
 * for any use, intended or otherwise.
 * This program may be used as source for other works as long 
 * as all material from the copyright statement to the end of this sentence
 * is retained in full without alteration.
 */
main()
{

struct proc *pp;

int i,cputime;
double pctcpu,logcpu,ccpu;

    /* open kmem and mem */
    if ((kmem = open(KMEM, 0)) < 0)
    {
	perror(KMEM);
	exit(1);
    }
    if ((mem = open(MEM, 0)) < 0)
    {
	perror(MEM);
	exit(1);
    }
    nlist(VMUNIX,nlst);
    getkval(nlst[X_CCPU].n_value,  &ccpu,  sizeof(int), nlst[X_CCPU].n_name);
    logcpu = log(ccpu);
while(1){
	system("clear");
	cu_des.p_max = MAX_PROC;
	cu_des.t_max = MAX_TEXT;
	cu_des.c_max = MAX_CMAP;
	status=cinfo(&cu_des,proc_v,text_v,cmap_v);

	if (status < 0){
	
		perror("cinfo");
		exit(-1);
	}

	proc_count = cu_des.p_ret;
	text_count = cu_des.t_ret;
	cmap_count = cu_des.c_ret;
	
	if (proc_count < 0 ){
	fprintf(stderr,"warning: not enough proc_v entries\n");
	proc_count = cu_des.p_max;
	}
	if (text_count < 0 ){
	fprintf(stderr,"warning: not enough text_v entries\n");
	text_count = cu_des.t_max;
	}
	if (cmap_count < 0 ){
	fprintf(stderr,"warning: not enough cmap_v entries\n");
	cmap_count = cu_des.c_max;
	}
	printf("\n  PID USERNAME PRI NICE   SIZE   RES STATE   TIME   WCPU    CPU COMMAND\n");

	    for (i = 0; i < proc_count; i++)
	    {
		pp = &proc_v[i];
		if (pp->p_pid !=0){
		if (getu(pp) == -1 || strlen(u.u_comm) == 0)
		{
		    strcpy(u.u_comm, "<swapped>");
		    cputime = 0;
		}
		else
		{
		    cputime = 
			(u.u_ru.ru_utime.tv_sec + u.u_ru.ru_stime.tv_sec);
		}

		pctcpu = pp->p_pctcpu;
		printf("%5d %-8.8s %3d %4d%6dK %4dK %-5s%4d:%02d %5.2f%% %5.2f%% %-14.14s\n",
		    pp->p_pid,
		    getpwuid(pp->p_uid)->pw_name,
		    pp->p_pri - PZERO,
		    pp->p_nice - NZERO,
		    (pp->p_tsize + pp->p_dsize + pp->p_ssize) >> 1,
		    pp->p_rssize >> 1,
		    state_abbrev[pp->p_stat],
		    cputime / 60l,
		    cputime % 60l,
		    pp->p_time == 0 ? 0.0 :
			pctcpu / (1.0 - exp(pp->p_time * logcpu)),
			pctcpu,
		    u.u_comm);
		}
	    }
      sleep(5);
    }
}

/*
 *  All of this stuff gets things out of the memory files.
 */

/*
 *  Get the user structure for the process who's proc structure is in p.  The
 *  user structure is returned in u.
 */
getu(p)

register struct proc *p;

{
    struct pte uptes[UPAGES];
    register caddr_t upage;
    register struct pte *pte;
    register nbytes, n;

    /*
     *  Check if the process is currently loaded or swapped out.  The way we
     *  get the u area is totally different for the two cases.  For this
     *  application, we just don't bother if the process is swapped out.
     */
    if ((p->p_flag & SLOAD) == 0)
    {
	return(-1);
    }

    /*
     *  Process is currently in memory, we hope!
     */
    if (!getkval(p->p_addr, uptes, sizeof(uptes), "p->p_addr"))
    {
	/* we can't seem to get to it, so pretend it's swapped out */
	return(-1);
    } 
    upage = (caddr_t)&u;
    pte = uptes;
    for (nbytes = sizeof(u); nbytes > 0; nbytes -= NBPG)
    {
    	lseek(mem, pte++->pg_pfnum * NBPG, 0);
	n = MIN(nbytes, NBPG);
	if (read(mem, upage, n) != n)
	{
	    /* we can't seem to get to it, so pretend it's swapped out */
	    return(-1);
	}
	upage += n;
    }
    return(0);
}
/*
 *  get the value of something from /dev/kmem
 */

getkval(offset, ptr, size, refstr)

long offset;
int *ptr;
int size;
char *refstr;

{
    if (lseek(kmem, offset, 0) == -1)
    {
	fprintf(stderr, "%s: lseek to %s: %s\n",
	    KMEM, refstr, sys_errlist[errno]);
	exit(1);
    }
    if (read(kmem, ptr, size) == -1)
    {
	if (strcmp(refstr, "p->p_addr") == 0) 
	{
	    /* we lost the race with the kernel, process isn't in memory */
	    return(0);
	} 
	else 
	{
	    fprintf(stderr, "%s: reading %s: %s\n",
		KMEM, refstr, sys_errlist[errno]);
	    exit(1);
	}
    }
    return(1);
}
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads