Monitor source part 7 of 9

jct jct at jct.UUCP
Tue Jul 11 14:31:19 AEST 1989


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 7 (of 9)."
# Contents:  monproc.c
# Wrapped by jct@ on Mon Jul 10 22:48:29 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'monproc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'monproc.c'\"
else
echo shar: Extracting \"'monproc.c'\" \(29415 characters\)
sed "s/^X//" >'monproc.c' <<'END_OF_FILE'
X/* System process activity monitor */
X
X/*
X*/
X
X/*
X   Created Sept 5, 1987 by JCT
X*/
X
X/*
X *	Copyright (c) John C. Tompkins 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal, noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the prior
X *      written consent of the author.  Please send modifications to the 
X *      author for inclusion in updates to the program.
X */
X
X/*
X   NOTE : This module uses 2 system compile time constants that I can't find at
X   run time. NSIG is the number of possible signals, I'm not too worried
X   about this. NOFILE is the maximum number of files a process may have open.
X   See this same constant in monitor2.c where configurations are displayed.
X   Neither of these are normal configuation parameters but still I wish I
X   knew where to find them at run time. The problem is if the program is
X   compiled on a system configured different than it is run on, problems
X   could result. I believe these are the only 2 compile time parameters in 
X   the entire program, everything else is found at run time.
X*/
X
X#include <stdio.h>
X#include <pwd.h>
X#include <grp.h>
X#include <fcntl.h>
X#include <ctype.h>
X
X#include <km/defs.h>
X#include <km/ascii.h>
X#include <km/scrio.h>
X#include <km/scrops.h>
X#include <km/string2.h>
X#include <km/monitor.h>		/* must come after defs.h and scrops.h */
X
X#define PROC_NORM    " (Q)uit, (T)op, (U)ser, (W)hen, (Z)ap, <SPACE> to backup or selection "
X#define PROC_MORE    " (Q)uit, (T)op, (U)ser, (S)witch, (W)hen, (Z)ap, <SPACE> to backup "
X#define PROC_PROMPT  " (Q)uit, (T)op, (S)witch, (W)hen, (Z)ap or <SPACE> to backup "
X
typedef struct
X  {
X    int      index;
X    int      flag;
X    ushort   count;
X    char     *itype;
X    ino_t    inumber;
X    long     offset;
X  } SFILE;
X
int         proc_pid, good_process, proc_mode = 1, proc_first;
int         proc_next, have_more;
long        mt_limit = 10, md_limit = 10, ms_limit = 10, uc_limit = 10;
long        urt_limit = 10, usw_limit = 10, uct_limit = 10;
long        uir_limit = 10, uiw_limit = 10;
long        proc_begin, run_time, last_interval;
SCR_ENTRY   proc_list[17];
SFILE       sfile[20];
int         open_fcount = 0, last_fcount = 0;
int	    last_scount = 0;
struct proc *proc_ptr, pbuf;
X
char *sig_name[] =
X  {
X    "Hangup",
X    "Interrupt",
X    "Quit",
X    "Illegal instruct",
X    "Trace trap",
X    "IOT",
X    "EMT",
X    "FP error",
X    "Kill",
X    "Bus error",
X    "Segment violation",
X    "Sys call error",
X    "Pipe write error",
X    "Alarm",
X    "Terminate",
X    "User 1",
X    "User 2",
X    "Death of child",
X    "Power fail"
X  };
X
extern int set_proc_menu();		/* forward reference */
extern int chk_key();
extern int show_user();
extern int show_proc();
extern int plot_proc();
extern int proc_chk_key();
X
SCR proc_menu = 
X  {
X    0,					/* window */
X    " User Process Monitor Menu ",	/* head */
X    set_proc_menu,			/* entry function */
X    show_user,				/* loop function */
X    chk_key,				/* check key function */
X    0,					/* prompt */
X    proc_list,				/* entry */
X    0,					/* active entry */
X    0,					/* last active */
X    5,					/* get key timeout */
X    "/usr/lib/help/monitor.hlp",	/* help file */
X    "proc",				/* help section */
X    (SCR_MENU | SCR_NO_REFRESH),	/* flags */
X    0,					/* local flags */
X    0					/* color */
X  };
X
SCR proc_scr =
X  {
X    0,					/* window */
X    " Process Monitor ",		/* head */
X    show_proc,				/* entry function */
X    plot_proc, 				/* loop function */
X    proc_chk_key,			/* check key function */
X    PROC_PROMPT,			/* prompt */
X    0,					/* entry */
X    0,					/* active entry */
X    0,					/* last active */
X    5,					/* get key timeout */
X    "/usr/lib/help/monitor.hlp",	/* help file */
X    "proc",				/* help section */
X    (SCR_NO_REFRESH | SCR_HELP_LOOP),	/* flags */
X    0,					/* local flags */
X    0					/* color */
X  };
X
X/*
X   Declare external UNIX functions
X*/
X
extern long lseek();
extern long time();
extern long times();
extern struct passwd *getpwnam();
extern struct passwd *getpwuid();
extern struct group *getgrgid();
X
static int show_user()
X{
X  struct passwd *pwent;
X
X  put_when(0, COLS - 24, curr_time, 0, FALSE);
X  move(0, 1);
X  addstr("User - ");
X  if (all_procs)
X    addstr("All");
X  else if (pwent = getpwuid(uid))
X    addstr(pwent->pw_name);
X  else
X    addstr("Unknown");
X  move(LINES - 1, 0);
X  refresh();
X}
X
static int uname_chk (statp, format)
X  IN_STAT *statp;
X  char    *format;
X{
X  if (statp->curr > statp->str)
X    {
X      if (isdigit (statp->ch))
X	return (statp->ch);
X      else if (isalpha (statp->ch))
X	return (tolower (statp->ch));
X      else
X	return (UNDETERMINED);
X    }
X  else
X    {
X      if (isalpha (statp->ch))
X        return (tolower (statp->ch));
X      else
X	return (UNDETERMINED);
X    }
X}
X
char *get_uname(win, string, max)
X  WINDOW *win;
X  char   *string;
X  int    max;
X{
X  char *stat;
X
X  if (string)
X    {
X      stat = wget_input(win, string, max, uname_chk, NULL, "/usr/lib/help/monitor.hlp", "user_name");
X      if (!stat)
X	return(NULL);
X    }
X  return(string);
X}
X
static int get_user()
X{
X  int           stat = FALSE;
X  char          buf[10];
X  WINDOW        *win;
X  struct passwd *pwent;
X
X  if (win = newwin(3, 45, 7, 15))
X    {
X      wsetcolor(win, (win->color & 0x0f), ((win->color >> 4) & 0x0f));
X      wclear(win);
X      box(win);
X      wmove(win, 1, 2);
X      waddstr(win, "Enter user name : ");
X      wrefresh(win);
X      buf[0] = '\0';
X      if ((get_uname(win, buf, sizeof(buf)) != NULL) && (buf[0] != '\0'))
X	{
X	  if (streq(buf, "all", TRUE))
X	    {
X	      all_procs = TRUE;
X	      stat = TRUE;
X	    }
X	  else if (pwent = getpwnam(buf))
X	    {
X	      uid = pwent->pw_uid;
X	      all_procs = FALSE;
X	      stat = TRUE;
X	    }
X	  else
X	    {
X	      wclear(win);
X	      wmove(win, 1, 2);
X	      wstandout(win);
X	      wprintw(win, " No such user : %s, Press any key ", buf);
X	      wstandend(win);
X	      wrefresh(win);
X	      move(LINES - 1, 0);
X	      refresh();
X	      get_key(UNDETERMINED);
X	    }
X	}
X      delwin(win, TRUE);
X    }
X  return(stat);
X}
X
static int chk_key(scr, key)
X  SCR *scr;
X  int key;
X{
X  int curr_pid;
X
X  switch (tolower(key))
X    {
X      case UNDETERMINED :
X	return(TRUE);
X	break;
X      case 's' :
X	if (have_more)
X	  {
X	    proc_first = proc_next;
X	    return(TRUE);
X	  }
X	break;
X      case 'u' :
X	if (get_user())
X	  {
X	    proc_first = 0;
X	    return(TRUE);
X	  }
X	break;
X      case 'w' :
X	if (get_interval())
X	  {
X	    mode_scr.timeout = sample_interval;
X	    proc_menu.timeout = sample_interval;
X	    return(TRUE);
X	  }
X	break;
X      case 'z' :
X	if (scr->active_entry)
X	  {
X    	    curr_pid = ((struct proc*)(scr->active_entry->pointer))->p_pid;
X	    kill(curr_pid, 9);
X	    return(TRUE);
X	  }
X	break;
X      default :
X	if (scr->active_entry = scr->entry)
X	  {
X	    while (scr->active_entry->key != UNDETERMINED)
X	      {
X		if (scr->active_entry->key == key)
X		  return(do_active_entry(scr));
X		else
X		  (scr->active_entry)++;
X	      }
X	    scr->active_entry = scr->last_active;
X	  }
X	break;
X    }
X  return(FALSE);
X}
X
void put_status(status)
X  int status;
X{
X  if (status == SSLEEP)
X    addstr("Sleeping ");
X  else if (status == SWAIT)
X    addstr("Abandoned");
X  else if (status == SRUN)
X    addstr("Running  ");
X  else
X    addstr("Unknown  ");
X}
X
void put_flags(flags)
X  int flags;
X{
X  clrtoeol();
X  if (flags & SLOAD)
X    addstr("Loaded ");
X  else
X    addstr("Swapped ");
X  if (flags & SSYS)
X    addstr("System ");
X  if (flags & SLOCK)
X    addstr("Locked ");
X  if (flags & SSWAP)
X    addstr("Swapping ");
X  if ((flags & STRC) || (flags & SWTED))
X    addstr("Trace ");
X  if (flags & STEXT)
X    addstr("Valid ");
X}
X
void put_signals(signals)
X  long signals;
X{
X  int i, mask, got_one = FALSE;
X
X  clrtoeol();
X  for (i = 0; i < NSIG; i++)
X    {
X      mask = 1;
X      mask <<= i;
X      if (signals & mask)
X	{
X	  if (got_one)
X	    addch(' ');
X	  got_one = TRUE;
X	  addstr(sig_name[i]);
X	}
X    }
X  if (!got_one)
X    addstr("None");
X}
X
void put_perms(perms)
X  int perms;
X{
X  char *p;
X
X  static char buf[20];
X
X  p = buf;
X  *p++ = ((perms & 0400) ? 'r' : '-');
X  *p++ = ((perms & 0200) ? 'w' : '-');
X  *p++ = ((perms & 0100) ? 'x' : '-');
X  *p++ = ((perms & 0040) ? 'r' : '-');
X  *p++ = ((perms & 0020) ? 'w' : '-');
X  *p++ = ((perms & 0010) ? 'x' : '-');
X  *p++ = ((perms & 0004) ? 'r' : '-');
X  *p++ = ((perms & 0002) ? 'w' : '-');
X  *p++ = ((perms & 0001) ? 'x' : '-');
X  *p = '\0';
X  addstr(buf);
X}
X
struct text *get_text(tptr)
X  struct text *tptr;
X{
X  int i;
X
X  if (tptr)
X    {
X      i = (int)(((unsigned int)tptr - offsets.text) / (long)sizeof(struct text));
X      if (i > v_buf.v_text)
X	return((struct text*)0);
X      read_text();
X      return(sptr.where.text + i);
X    }
X  else
X    return((struct text*)0);
X}
X
int get_tcount(tptr)
X  struct text tptr;
X{
X  struct text *p;
X
X  if (p = get_text(tptr))
X    return(p->x_count);
X  return(0);
X}
X
struct file *get_file(fptr)
X  filep_t fptr;
X{
X  int i;
X
X  if (fptr)
X    {
X      i = (int)((((long)fptr & 0x0ffff) + offsets.end + offsets.mem - 
X	  offsets.file) / (long)sizeof(struct file));
X      if (i > v_buf.v_file)
X	return((struct file*)0);
X      return(file_buf + i);
X    }
X  else
X    return((struct file*)0);
X}
X
struct inode *get_inode(iptr)
X  inodep_t iptr;
X{
X  int i;
X
X  if (iptr)
X    {
X      i = (int)((((long)iptr & 0x0ffff) + offsets.end + offsets.mem - 
X	  offsets.inode) / (long)sizeof(struct inode));
X      if (i > v_buf.v_inode)
X	return((struct inode*)0);
X      read_inode();
X      return(sptr.where.inode + i);
X    }
X  else
X    return((struct inode*)0);
X}
X
char *get_itype(iptr)
X  inodep_t iptr;
X{
X  struct inode *p;
X
X  if (p = get_inode(iptr))
X    {
X      switch (p->i_mode & IFMT)
X	{
X	  case IFDIR :
X	    return("D ");
X	    break;
X	  case IFCHR :
X	    return("C ");
X	    break;
X	  case IFBLK :
X	    return("B ");
X	    break;
X	  case IFREG :
X	    return("  ");
X	    break;
X	  case IFMPC :
X	    return("CX");
X	    break;
X	  case IFMPB :
X	    return("BX");
X	    break;
X	  case IFIFO :
X	    return("F ");
X	    break;
X	}
X    }
X  return("? ");
X}
X
ino_t get_inumber(iptr)
X  inodep_t iptr;
X{
X  struct inode *p;
X
X  if (p = get_inode(iptr))
X    return(p->i_number);
X  return(0);
X}
X
int stat_files (user_ptr)
X  struct user *user_ptr;
X{
X  int 	      i;
X  struct file *fp, fbuf;
X
X  for (i = 0, open_fcount = 0; (i < NOFILE) && (open_fcount < (LINES - 8)); i++)
X    {
X      if (user_ptr->u_ofile[i])
X	{
X	  if (fp = get_file(user_ptr->u_ofile[i]))
X	    {
X	      memcpy (&fbuf, fp, sizeof (fbuf));
X	      sfile[open_fcount].index = i;
X	      sfile[open_fcount].flag = fbuf.f_flag;
X	      sfile[open_fcount].count = fbuf.f_count;
X	      sfile[open_fcount].itype = get_itype(fbuf.f_inode);
X	      sfile[open_fcount].inumber = get_inumber(fbuf.f_inode);
X	      sfile[open_fcount].offset = fbuf.f_un.f_off;
X              open_fcount++;
X	    }
X	}
X    }
X}
X
void show_files()
X{
X  int i;
X
X  move(LINE_1 + 1, COL_2 + 3);
X  addstr("Fid Typ Mode Cnt Offset     I-node");
X  for (i = 0; i < open_fcount; i++)
X    {
X      move(LINE_1 + 2 + i, COL_2 + 3);
X      printw("%-3d ", sfile[i].index);
X      printw("%s  ", sfile[i].itype);
X      addch((sfile[i].flag & FREAD) ? 'R' : ' ');
X      addch((sfile[i].flag & FWRITE) ? 'W' : ' ');
X      addch((sfile[i].flag & FNDELAY) ? 'N' : ' ');
X      addch((sfile[i].flag & FAPPEND) ? 'A' : ' ');
X      addch(' ');
X      printw("%-3d ", sfile[i].count);
X      printw("%-10ld ", sfile[i].offset);
X      printw("%-6u", sfile[i].inumber);
X    }
X  for (i = open_fcount; i < last_fcount; i++)
X    {
X      move(LINE_1 + 2 + i, COL_2 + 3);
X      clrtoeol();
X    }
X  last_fcount = open_fcount;
X}
X
void show_signals(user_ptr)
X  struct user *user_ptr;
X{
X  int i, mod_count;
X
X  for (i = 0, mod_count = 0; (i < NSIG) && (mod_count < (LINES - 17)); i++)
X    {
X      if (user_ptr->u_signal[i] == (int (far *)())0)
X	;
X      else if (user_ptr->u_signal[i] == (int (far *)())1)
X	{
X	  move(LINE_1 + 8 + mod_count, COL_1);
X	  clrtoeol();
X	  printw("Signal %-18s Ignored", sig_name[i]);
X	  mod_count++;
X	}
X      else
X	{
X	  move(LINE_1 + 8 + mod_count, COL_1);
X	  clrtoeol();
X	  printw("Signal %-18s Trapped", sig_name[i]);
X	  mod_count++;
X	}
X    }
X  for (i = mod_count; i < last_scount; i++)
X    {
X      move(LINE_1 + 8 + i, COL_1);
X      clrtoeol();
X    }
X  last_scount = mod_count;
X}
X
void put_uid(p)
X  struct user *p;
X{
X  struct passwd *pwent;
X
X  if (pwent = getpwuid(p->u_ruid))		/* real uid */
X    addstr(pwent->pw_name);
X  else
X    addstr("Unknown");
X  addstr(", ");
X  if (pwent = getpwuid(p->u_uid))		/* effective uid */
X    addstr(pwent->pw_name);
X  else
X    addstr("Unknown");
X  endpwent();
X}
X
void put_gid(p)
X  struct user *p;
X{
X  struct group *grent;
X
X  if (grent = getgrgid(p->u_rgid))		/* real gid */
X    addstr(grent->gr_name);
X  else
X    addstr("Unknown");
X  addstr(", ");
X  if (grent = getgrgid(p->u_gid))		/* effective gid */
X    addstr(grent->gr_name);
X  else
X    addstr("Unknown");
X  endgrent();
X}
X
void do_plot_proc()
X{
X  int  i, open_count, text_count;
X  long cpu_time, usr_time, sys_time;
X  long text_size, data_size, stack_size;
X
X  if (good_process)
X    {
X      if (user_new.u_start)
X        run_time = time((long*)0) - user_last.u_start; 
X      else
X        run_time = 0;
X    }
X  if (proc_mode == 1)
X    {
X      for (i = 0, open_count = 0; i < NOFILE; i++)
X        {
X          if (user_new.u_ofile[i])
X            open_count++;
X        }
X      usr_time = user_new.u_utime / hz;
X      sys_time = user_new.u_stime / hz;
X      cpu_time = (user_new.u_utime + user_new.u_stime) / hz;
X      bar_percent(LINE_1, COL_1, (user_new.u_utime - user_last.u_utime), time_interval);
X      bar_percent(LINE_2, COL_1, (user_new.u_stime - user_last.u_stime), time_interval);
X      bar_persec(LINE_3, COL_1, (user_new.u_ioch - user_last.u_ioch), &uc_limit, 10L);
X      if ((user_new.u_ruid != user_last.u_ruid) ||
X	  (user_new.u_uid != user_last.u_uid))
X	{
X          move(LINE_1 + 2, COL_2 + 18);
X          put_uid(&user_new);
X	}
X      if ((user_new.u_rgid != user_last.u_rgid) ||
X	  (user_new.u_gid != user_last.u_gid))
X	{
X          move(LINE_1 + 3, COL_2 + 18);
X          put_gid(&user_new);
X	}
X      move(LINE_1 + 5, COL_2 + 18);
X      printw("%-10d", pbuf.p_ppid);
X      move(LINE_1 + 6, COL_2 + 18);
X      printw("%-10d", pbuf.p_pgrp);
X      move(LINE_1 + 7, COL_2 + 18);
X      put_status(pbuf.p_stat);
X      move(LINE_1 + 8, COL_2 + 18);
X      put_flags(pbuf.p_flag);
X      move(LINE_1 + 9, COL_2 + 18);
X      printw("%d, %-5d", pbuf.p_pri, pbuf.p_nice);
X      move(LINE_1 + 10, COL_2 + 18);
X      if (run_time)
X        printw("%-10ld", run_time);
X      else
X	addstr("Unknown");
X      move(LINE_1 + 11, COL_2 + 18);
X      if (run_time)
X        printw("%-10ld - %ld%%    ", cpu_time, ((cpu_time * 100) / run_time));
X      else
X        printw("%-10ld            ", cpu_time);
X      move(LINE_1 + 12, COL_2 + 18);
X      if (run_time)
X        printw("%-10ld - %ld%%    ", usr_time, ((usr_time * 100) / run_time));
X      else
X        printw("%-10ld            ", usr_time);
X      move(LINE_1 + 13, COL_2 + 18);
X      if (run_time)
X        printw("%-10ld - %ld%%    ", sys_time, ((sys_time * 100) / run_time));
X      else
X        printw("%-10ld            ", sys_time);
X      move(LINE_1 + 14, COL_2 + 18);
X      printw("%-10d", open_count);
X      move(LINE_1 + 15, COL_2 + 18);
X      printw("%-10ld", user_new.u_ior);
X      move(LINE_1 + 16, COL_2 + 18);
X      printw("%-10ld", user_new.u_iow);
X      move(LINE_1 + 17, COL_2 + 18);
X      printw("%-10ld", user_new.u_ioch);
X      move(LINE_1 + 18, COL_2 + 18);
X      printw("%-10d", get_inumber(user_last.u_cdir));
X      move(LINE_1 + 19, COL_2 + 18);
X      printw("%-10d", get_inumber(user_last.u_rdir));
X    }
X  else
X    {
X#ifdef XENIX
X      text_size = user_new.u_tsize * 512L;
X      data_size = user_new.u_dsize * 512L;
X      stack_size = user_new.u_ssize * 512L;
X#else
X      text_size = user_new.u_tsize * NBPC;
X      data_size = user_new.u_dsize * NBPC;
X      stack_size = user_new.u_ssize * NBPC;
X#endif
X      text_count = get_tcount(pbuf.p_textp);
X      move(LINE_1, COL_1 + 18);
X      put_perms(user_new.u_cmask);
X      move(LINE_1 + 1, COL_1 + 18);
X      printw("%-10ld", user_new.u_limit);
X      move(LINE_1 + 2, COL_1 + 18);
X      printw("%ld/%-15d", text_size, text_count);
X      move(LINE_1 + 3, COL_1 + 18);
X      printw("%-10ld", data_size);
X      move(LINE_1 + 4, COL_1 + 18);
X      printw("%-10ld", stack_size);
X      move(LINE_1 + 5, COL_1 + 18);
X      put_signals(pbuf.p_sig);
X      move(LINE_1 + 6, COL_1 + 18);
X      printw("%-10u", pbuf.p_clktim);
X      show_signals(&user_new);
X      show_files();
X    }
X}
X
int read_proc(user_ptr)
X  struct user *user_ptr;
X{
X  int 	      i, stat = FALSE;
X
X  if ((lseek(kfd, offsets.proc, 0) != ERROR) &&
X      (read(kfd, proc_buf, proc_size) != ERROR))
X    {
X      for (i = 0, proc_ptr = proc_buf; i < v_buf.v_proc; i++, proc_ptr++)
X	{
X	  if (proc_ptr->p_stat && (proc_ptr->p_pid == proc_pid))
X	    {
X	      memcpy (&pbuf, proc_ptr, sizeof (pbuf));
X  	      if (pbuf.p_flag & SLOAD)
X    		{
X#ifdef XENIX
X      		  offsets.user = pbuf.p_addr.p_caddr * 512L;
X#else
X      		  offsets.user = (pbuf.p_addr[0] * (long)NBPC) + 0x600L;
X#endif
X      		  ufd = mfd;
X    		}
X  	      else
X    		{
X#ifdef XENIX
X      		  offsets.user = (pbuf.p_addr.p_daddr + swplo) * BSIZE;
X#else
X      		  offsets.user = (pbuf.p_swaddr + swplo) * BSIZE;
X#endif
X      		  ufd = sfd;
X    		}
X      	      if ((lseek(ufd, offsets.user, 0) != ERROR) &&
X          	  (read(ufd, user_ptr, sizeof(struct user)) != ERROR))
X		{
X#ifdef XENIX
X		  if (proc_pid == 0)
X		    user_ptr->u_start = boot_time;
X#endif
X		  if (user_ptr->u_procp ==
X		      (struct proc near*)(offsets.proc + i * sizeof(struct proc)))
X		    stat = TRUE;
X		}
X	      break;
X	    }
X	}
X    }
X  if (stat)
X    stat_files (user_ptr);
X  return(stat);
X}
X
int plot_proc()
X{
X#ifdef SYSV
X  int i;
X#endif
X
X  put_when(0, COLS - 24, curr_time, 0, FALSE);
X  if (!read_data(FALSE))
X    return(FALSE);
X  if (read_proc(&user_new))
X    {
X      user_last = user_llast;
X      last_interval = time_interval;
X    }
X  else
X    {
X      user_new = user_llast;
X      time_interval = last_interval;
X      good_process = FALSE;
X    }
X  do_plot_proc();
X  if (good_process)
X    user_llast = user_new;
X  else
X    {
X      move(0, 1);
X      standout();
X      addstr(" Terminated ");
X      standend();
X      printw(" - %s", proc_name);
X    }
X  move(LINES - 1, 0);
X  refresh();
X}
X
char *get_tty_name()
X{
X  int    i, inumber = 0, fd, got_it = FALSE;
X  struct direct dev_entry;
X  SPTR	 ptr;
X
X  static char tty[DIRSIZ + 1];
X
X  read_inode();
X  ptr = sptr;
X  tty[0] = '\0';
X  for (i = v_buf.v_inode; i; i--)
X    {
X      if ((((ptr.where.inode->i_mode & IFCHR) == IFCHR) ||
X	   ((ptr.where.inode->i_mode & IFMPC) == IFMPC)) &&
X	  (ptr.where.inode->i_fdep.i_namef.i_type == user_last.u_ttyd))
X	{
X	  inumber = ptr.where.inode->i_number;
X	  if ((fd = open("/dev", O_RDONLY)) != ERROR)
X	    {
X	      while (!got_it && (read(fd, &dev_entry, sizeof(struct direct)) > 0))
X		{
X		  if (dev_entry.d_ino == inumber)
X		    got_it = TRUE;
X		}
X	      if (got_it)
X	 	{
X		  strncpy(tty, dev_entry.d_name, DIRSIZ);
X		  tty[DIRSIZ] = '\0';
X		}
X	      close(fd);
X	    }
X	  break;
X	}
X      ptr.where.inode++;
X    }
X  return(tty);
X}
X
int show_proc()
X{
X  int           i, open_count, text_count;
X  long		cpu_time, usr_time, sys_time;
X  long          text_size, data_size, stack_size;
X
X  erase();
X  move(0, 1);
X  printw("%d - %s", proc_pid, proc_name);
X  put_when(0, COLS - 24, curr_time, 0, FALSE);
X  if (good_process)
X    {
X      if (user_last.u_start)
X        run_time = time((long*)0) - user_last.u_start; 
X      else
X        run_time = 0;
X    }
X  if (proc_mode == 1)
X    {
X      for (i = 0, open_count = 0; i < NOFILE; i++)
X        {
X          if (user_last.u_ofile[i])
X            open_count++;
X        }
X      usr_time = user_last.u_utime / hz;
X      sys_time = user_last.u_stime / hz;
X      cpu_time = (user_last.u_utime + user_last.u_stime) / hz;
X      chart_percent(LINE_1, COL_1, "% CPU User");
X      chart_percent(LINE_2, COL_1, "% CPU System");
X      chart_absolute(LINE_3, COL_1, "I/O Chars / Second", uc_limit);
X      move(LINE_1, COL_2);
X      addstr("Start Time      : ");
X      if (proc_begin > 0)
X        put_time(LINE_1, COL_2 + 18, proc_begin, TIME_SECONDS, FALSE);
X      else
X	{
X	  move(LINE_1, COL_2 + 18);
X	  addstr("Unknown");
X	}
X      move(LINE_1 + 1, COL_2);
X      addstr("Start Date      : ");
X      if (proc_begin > 0)
X        put_date(LINE_1 + 1, COL_2 + 18, proc_begin, 0, FALSE);
X      else
X	{
X	  move(LINE_1 + 1, COL_2 + 18);
X	  addstr("Unknown");
X	}
X      move(LINE_1 + 2, COL_2);
X      addstr("User ID         : ");
X      move(LINE_1 + 2, COL_2 + 18);
X      put_uid(&user_last);
X      move(LINE_1 + 3, COL_2);
X      addstr("Group ID        : ");
X      move(LINE_1 + 3, COL_2 + 18);
X      put_gid(&user_last);
X      move(LINE_1 + 4, COL_2);
X      addstr("TTY             : ");
X      move(LINE_1 + 4, COL_2 + 18);
X      addstr(get_tty_name());
X      move(LINE_1 + 5, COL_2);
X      addstr("Parent PID      : ");
X      move(LINE_1 + 5, COL_2 + 18);
X      printw("%-10d", pbuf.p_ppid);
X      move(LINE_1 + 6, COL_2);
X      addstr("Process Group   : ");
X      move(LINE_1 + 6, COL_2 + 18);
X      printw("%-10d", pbuf.p_pgrp);
X      move(LINE_1 + 7, COL_2);
X      addstr("Process Status  : ");
X      move(LINE_1 + 7, COL_2 + 18);
X      put_status(pbuf.p_stat);
X      move(LINE_1 + 8, COL_2);
X      addstr("Process Flags   : ");
X      move(LINE_1 + 8, COL_2 + 18);
X      put_flags(pbuf.p_flag);
X      move(LINE_1 + 9, COL_2);
X      addstr("Priority        : ");
X      move(LINE_1 + 9, COL_2 + 18);
X      printw("%d, %-5d", pbuf.p_pri, pbuf.p_nice);
X      move(LINE_1 + 10, COL_2);
X      addstr("Run Time        : ");
X      move(LINE_1 + 10, COL_2 + 18);
X      if (run_time)
X        printw("%-10ld", run_time);
X      else
X	addstr("Unknown");
X      move(LINE_1 + 11, COL_2);
X      addstr("Total CPU Time  : ");
X      move(LINE_1 + 11, COL_2 + 18);
X      if (run_time)
X        printw("%-10ld - %ld%%    ", cpu_time, ((cpu_time * 100) / run_time));
X      else
X        printw("%-10ld            ", cpu_time);
X      move(LINE_1 + 12, COL_2);
X      addstr("CPU User Time   : ");
X      move(LINE_1 + 12, COL_2 + 18);
X      if (run_time)
X        printw("%-10ld - %ld%%    ", usr_time, ((usr_time * 100) / run_time));
X      else
X        printw("%-10ld            ", usr_time);
X      move(LINE_1 + 13, COL_2);
X      addstr("CPU Sys Time    : "); 
X      move(LINE_1 + 13, COL_2 + 18);
X      if (run_time)
X        printw("%-10ld - %ld%%    ", sys_time, ((sys_time * 100) / run_time));
X      else
X        printw("%-10ld            ", sys_time);
X      move(LINE_1 + 14, COL_2);
X      addstr("Open Files      : ");
X      move(LINE_1 + 14, COL_2 + 18);
X      printw("%-10d", open_count);
X      move(LINE_1 + 15, COL_2);
X      addstr("Block Reads     : ");
X      move(LINE_1 + 15, COL_2 + 18);
X      printw("%-10ld", user_last.u_ior);
X      move(LINE_1 + 16, COL_2);
X      addstr("Block Writes    : ");
X      move(LINE_1 + 16, COL_2 + 18);
X      printw("%-10ld", user_last.u_iow);
X      move(LINE_1 + 17, COL_2);
X      addstr("I/O Count       : ");
X      move(LINE_1 + 17, COL_2 + 18);
X      printw("%-10ld", user_last.u_ioch);
X      move(LINE_1 + 18, COL_2);
X      addstr("Curr Dir I-node : ");
X      move(LINE_1 + 18, COL_2 + 18);
X      printw("%-10d", get_inumber(user_last.u_cdir));
X      move(LINE_1 + 19, COL_2);
X      addstr("Root Dir I-node : ");
X      move(LINE_1 + 19, COL_2 + 18);
X      printw("%-10d", get_inumber(user_last.u_rdir));
X    }
X  else
X    {
X#ifdef XENIX
X      text_size = user_last.u_tsize * 512L;
X      data_size = user_last.u_dsize * 512L;
X      stack_size = user_last.u_ssize * 512L;
X#else
X      text_size = user_last.u_tsize * NBPC;
X      data_size = user_last.u_dsize * NBPC;
X      stack_size = user_last.u_ssize * NBPC;
X#endif
X      text_count = get_tcount(pbuf.p_textp);
X      move(LINE_1, COL_1);
X      addstr("Umask Value     : ");
X      move(LINE_1, COL_1 + 18);
X      put_perms(user_last.u_cmask);
X      move(LINE_1 + 1, COL_1);
X      addstr("Ulimit Value    : ");
X      move(LINE_1 + 1, COL_1 + 18);
X      printw("%-10ld", user_last.u_limit);
X      move(LINE_1 + 2, COL_1);
X      addstr("Text Size       : ");
X      move(LINE_1 + 2, COL_1 + 18);
X      printw("%ld/%-15d", text_size, text_count);
X      move(LINE_1 + 3, COL_1);
X      addstr("Data Size       : ");
X      move(LINE_1 + 3, COL_1 + 18);
X      printw("%-10ld", data_size);
X      move(LINE_1 + 4, COL_1);
X      addstr("Stack Size      : ");
X      move(LINE_1 + 4, COL_1 + 18);
X      printw("%-10ld", stack_size);
X      move(LINE_1 + 5, COL_1);
X      addstr("Pending Signals : ");
X      move(LINE_1 + 5, COL_1 + 18);
X      put_signals(pbuf.p_sig);
X      move(LINE_1 + 6, COL_1);
X      addstr("Time to Alarm   : ");
X      move(LINE_1 + 6, COL_1 + 18);
X      printw("%-10u", pbuf.p_clktim);
X      show_signals(&user_last);
X      move(LINE_1, COL_2 + 12);
X      addstr("Open File Status");
X      show_files();
X    }
X}
X
int proc_chk_key(scr, key)
X  SCR *scr;
X  int key;
X{
X  switch (tolower(key))
X    {
X      case 's' :
X	if (proc_mode == 1)
X	  proc_mode = 2;
X	else
X	  proc_mode = 1;
X	show_proc();
X	return(TRUE);
X	break;
X      case 'w' :
X	if (get_interval())
X	  {
X	    mode_scr.timeout = sample_interval;
X	    proc_scr.timeout = sample_interval;
X	    proc_menu.timeout = sample_interval;
X	    return(TRUE);
X	  }
X	break;
X      case 'z' :
X	kill(proc_pid, 9);
X	return(TRUE);
X	break;
X      default :
X	break;
X    }
X  return(FALSE); 
X}
X
char *get_proc_name(pptr, user_ptr, extra)
X  struct proc *pptr;
X  struct user *user_ptr;
X  int         extra;
X{
X  int  i, percent;
X  char *in_ptr, *start_name, buf[30];
X
X  start_name = name_ptr;
X  if (extra)
X    {
X      percent = (int)((pptr->p_cpu * 100) / cpu_total);
X      if (percent > 100)
X	percent = 100;
X      if (percent)
X        sprintf(buf, "%-5d - %3d%% - ", pptr->p_pid, percent);
X      else
X        sprintf(buf, "%-5d -      - ", pptr->p_pid);
X      for (in_ptr = buf; *in_ptr; in_ptr++)
X        *name_ptr++ = *in_ptr;
X    }
X  if (pptr->p_pid == 0)
X    in_ptr = "swapper";
X  else if (pptr->p_pid == 1)
X    in_ptr = "init";
X  else if (pptr->p_pid == 2)
X    in_ptr = "pager";
X  else
X    in_ptr = user_ptr->u_comm;
X  for (i = 0; *in_ptr && (*in_ptr != ' ') && (*in_ptr != '\t') && (i < DIRSIZ); in_ptr++, i++)
X    *name_ptr++ = *in_ptr;
X  *name_ptr++ = '\0';
X  return(start_name);
X}
X
int do_proc(pptr)
X  struct proc *pptr;
X{
X  int  i;
X  char *in_ptr;
X
X  ms_limit = 10;
X  mt_limit = 10;
X  md_limit = 10;
X  uc_limit = 10;
X  urt_limit = 10;
X  uct_limit = 10;
X  usw_limit = 10;
X  uir_limit = 10;
X  uiw_limit = 10;
X  open_fcount = 0;
X  last_fcount = 0;
X  last_scount = 0;
X  proc_pid = pptr->p_pid;
X  if (read_proc(&user_last))
X    {
X      good_process = TRUE;
X      user_llast = user_last;
X      proc_begin = user_last.u_start;
X      run_time = curr_time - proc_begin;
X      last_interval = time_interval;
X      proc_name = get_proc_name(pptr, &user_last, FALSE);
X      proc_scr.timeout = sample_interval;
X      do_scr(&proc_scr);
X    }
X  return(TRUE);
X}
X
int set_proc_menu()
X{
X  int       i, j, curr_pid;
X  SCR_ENTRY *pl_ptr;
X
X  if (proc_menu.active_entry)
X    curr_pid = ((struct proc*)(proc_menu.active_entry->pointer))->p_pid;
X  else
X    curr_pid = UNDETERMINED;
X  proc_menu.active_entry = (SCR_ENTRY*)0;
X  proc_menu.last_active = (SCR_ENTRY*)0;
X  j = 0;
X  name_ptr = name_buf;
X  have_more = FALSE;
X  if (read_data(TRUE))
X    {
X      do
X	{
X          for (i = proc_first, pl_ptr = proc_list, proc_ptr = &proc_buf[proc_first]; i < v_buf.v_proc; i++, proc_ptr++)
X	    {
X	      if (proc_ptr->p_stat && (all_procs || (proc_ptr->p_uid == uid)))
X	        {
X	          if (j  >= 16)
X		    {
X		      have_more = TRUE;
X		      break;
X		    }
X  	          if (proc_ptr->p_flag & SLOAD)
X    		    {
X#ifdef XENIX
X      		      offsets.user = proc_ptr->p_addr.p_caddr * 512L;
X#else
X      		      offsets.user = (proc_ptr->p_addr[0] * (long)NBPC) + 0x600L;
X#endif
X      		      ufd = mfd;
X    		    }
X  	          else
X    		    {
X#ifdef XENIX
X      		      offsets.user = (proc_ptr->p_addr.p_daddr + swplo) * BSIZE;
X#else
X      		      offsets.user = (proc_ptr->p_swaddr + swplo) * BSIZE;
X#endif
X      		      ufd = sfd;
X    		    }
X      	          if ((lseek(ufd, offsets.user, 0) != ERROR) &&
X          	      (read(ufd, &user_new, sizeof(struct user)) != ERROR))
X		    {
X	              pl_ptr->key = 0;
X	              pl_ptr->text = get_proc_name(proc_ptr, &user_new, TRUE);
X	              pl_ptr->func = do_proc;
X	              pl_ptr->pointer = (char*)proc_ptr;
X	              pl_ptr->help_section = "proc";
X	              pl_ptr->flags = SCR_PPARM;
X		      if (proc_ptr->p_pid == curr_pid)
X			{
X			  proc_menu.active_entry = pl_ptr;
X			  proc_menu.last_active = pl_ptr;
X			}
X	              j++;
X		      pl_ptr++;
X		    }
X	        }
X	    }
X          if (j == 0)
X	    {
X	      if (proc_first != 0)
X	        proc_first = 0;
X	      else
X		break;
X	    }
X	}
X      while (j == 0);
X    }
X  proc_next = i;
X  if (proc_next >= v_buf.v_proc)
X    proc_next = 0;
X  if (proc_first != 0)
X    have_more = TRUE;
X  if (have_more)
X    proc_menu.prompt = PROC_MORE;
X  else
X    proc_menu.prompt = PROC_NORM;
X  pl_ptr->key = UNDETERMINED;
X  proc_menu.lflags &= ~SCR_SETKEYS;
X}
X
void do_proc_menu()
X{
X  proc_first = 0;
X  proc_menu.timeout = sample_interval;
X  do_scr(&proc_menu);
X}
X
END_OF_FILE
if test 29415 -ne `wc -c <'monproc.c'`; then
    echo shar: \"'monproc.c'\" unpacked with wrong size!
fi
# end of 'monproc.c'
fi
echo shar: End of archive 7 \(of 9\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 9 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0



More information about the Comp.unix.xenix mailing list