::: 강좌/소스/문서 :::

강좌/소스/문서 성격에 맞지 않는 광고,비방,질문의 글은 즉시 삭제하며
내용을 복사하여 사용할 경우 반드시 이곳(http://www.howto.pe.kr)을 출처로 명시하여 주세요


Category

  김영대(2004-02-20 13:07:28, Hit : 14752, Vote : 1261
 http://www.howto.pe.kr
 [소스] top for SunOS 5.x (Solaris 2.x)

Check out:

    eecs.nwu.edu:/pub/top/top-3.3beta3.tar.gz

Included below is a patched version of machine/m_sunos5.c which does
the right thing with cpu stats for multiprocessor machines.  It also
uses the /dev/kstat interface to get all of the necessary information
instead of poking around in kernel memory directly.

Brett McCoy, UNIX Systems Administrator
Computing and Network Services
Kansas State University,  Manhattan KS  66506
vox: (913) 532-4908 / fax: (913) 532-5914 / e-mail: brtmac@ksu.ksu.edu

======================================================================
/*
* top - a top users display for Unix
*
* SYNOPSIS:  Any Sun running SunOS 5.x (Solaris 2.x)
*
* DESCRIPTION:
* This is the machine-dependent module for SunOS 5.x (Solaris 2).
* There is some support for MP architectures.
* This makes top work on the following systems:
*         SunOS 5.0 (not tested)
*         SunOS 5.1
*         SunOS 5.2
*
*     Tested on a SPARCclassic with SunOS 5.1, using gcc-2.3.3, and
*     SPARCsystem 600 with SunOS 5.2, using Sun C
*
* LIBS: -R/usr/lib -lelf -lkvm -lkstat
*
*
* AUTHORS:      Torsten Kasch   <torsten@techfak.uni-bielefeld.de>
*               Robert Boucher  <boucher@sofkin.ca>
* CONTRIBUTORS: Marc Cohen   <marc@aai.com>
*               Charles Hedrick  <hedrick@geneva.rutgers.edu>
*          William L. Jones  <jones@chpc>
*               Petri Kutvonen         <kutvonen@cs.helsinki.fi>
*/
#define _KMEMUSER
#include "top.h"
#include "machine.h"
#include "utils.h"
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <dirent.h>
#include <nlist.h>
#include <string.h>
#include <kstat.h>
#include <kvm.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/signal.h>
#include <sys/fault.h>
#include <sys/sysinfo.h>
#include <sys/sysmacros.h>
#include <sys/syscall.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/procfs.h>
#include <sys/vm.h>
#include <sys/var.h>
#include <sys/cpuvar.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/priocntl.h>
#include <sys/tspriocntl.h>
#include <sys/processor.h>
#include <vm/anon.h>
#include <math.h>

#define UNIX "/dev/ksyms"
#define KMEM "/dev/kmem"
#define PROCFS "/proc"
#define CPUSTATES     5
#ifndef PRIO_MIN
#define PRIO_MIN -20
#endif
#ifndef PRIO_MAX
#define PRIO_MAX 20
#endif

#ifndef FSCALE
#define FSHIFT  8  /* bits to right of fixed binary point */
#define FSCALE  (1<<FSHIFT)
#endif /* FSCALE */

#define loaddouble(la) ((double)(la) / FSCALE)
#define percent_cpu(pp) (*(double *)pp->pr_filler)
#define weighted_cpu(pp) (*(double *)&pp->pr_filler[2])
#undef ctob
#define ctob(x) ((x) << 12)
#define pagetok(size) ctob(size) >> LOG1024

/* definitions for indices in the nlist array */
#define X_MPID    0
#define X_MAXMEM   1

static struct nlist nlst[] =
{
  {"mpid"},   /* 0 */
  {"maxmem"},   /* 1 */
  {0}
};

static unsigned long mpid_offset;
static unsigned long maxmem_offset;

/* get_process_info passes back a handle.  This is what it looks like: */
struct handle
  {
    struct prpsinfo **next_proc;/* points to next valid proc pointer */
    int remaining;  /* number of pointers remaining */
  };

/*
* Structure for keeping track of CPU times from last time around
* the program.  We keep these things in a hash table, which is
* recreated at every cycle.
*/
struct oldproc
  {
    pid_t oldpid;
    double oldtime;
    double oldpct;
  };
int oldprocs;   /* size of table */
#define HASH(x) ((x << 1) % oldprocs)

/*
* GCC assumes that all doubles are aligned.  Unfortunately it
* doesn't round up the structure size to be a multiple of 8.
* Thus we'll get a coredump when going through array.  The
* following is a size rounded up to 8.
*/
#define PRPSINFOSIZE (((sizeof(struct prpsinfo) + 7) / 8) * 8)
/*
*  These definitions control the format of the per-process area
*/
static char header[] =
"  PID X        PRI NICE  SIZE   RES STATE   TIME   WCPU    CPU COMMAND";
/* 0123456   -- field to fill in starts at header+6 */
#define UNAME_START 6

#define Proc_format
        "%5d %-8.8s %3d %4d %5s %5s %-5s %6s %5.2f%% %5.2f%% %s"

/* process state names for the "STATE" column of the display */
/* the extra nulls in the string "run" are for adding a slash and
   the processor number when needed */
char *state_abbrev[] =
{"", "sleep", "run", "zombie", "stop", "start", "cpu", "swap"};

int process_states[8];
char *procstatenames[] =
{
  "", " sleeping, ", " running, ", " zombie, ", " stopped, ",
  " starting, ", " on cpu, ", " swapped, ",
  NULL
};

int cpu_states[CPUSTATES];
char *cpustatenames[] =
{"idle", "user", "kernel", "iowait", "swap", NULL};

/* these are for detailing the memory statistics */
int memory_stats[5];
char *memorynames[] =
{"K real, ", "K kernel, ", "K free, ", "K swap, ", "K free swap", NULL};

kvm_t *kd;
kstat_ctl_t *kstat_ctl;
static DIR *procdir;
static int nproc;
static int ncpus;
static int pagesize;
static int *cpu_stats;
static sysinfo_t sysinfo;
static vminfo_t  vminfo;

/* these are for keeping track of the proc array */
static int bytes;
static struct prpsinfo *pbase;
static struct prpsinfo **pref;
static struct oldproc *oldbase;

/* useful externals */
extern int errno;
extern char *sys_errlist[];
extern char *myname;
extern int check_nlist ();
extern int gettimeofday ();
extern int getkval ();
extern int get_system_misc ();
extern int getkstatval ();
extern void perror ();
extern void getptable ();
extern void quit ();
extern int nlist ();

int
machine_init (struct statics *statics)
  {
    static struct var v;
    struct oldproc *op, *endbase;
    int  n, i;
    kstat_t  *kstat;
    kstat_named_t *kstat_named;
    char buf[32];
    processor_info_t pi;
    /* fill in the statics information */
    statics->procstate_names = procstatenames;
    statics->cpustate_names = cpustatenames;
    statics->memory_names = memorynames;

    pagesize = sysconf(_SC_PAGESIZE);

    if ((kstat_ctl = kstat_open()) == NULL) {
perror("kstat_open");
return(-1);
    }
    if ((kd = kvm_open (NULL, NULL, NULL, O_RDONLY, "top")) == NULL)
      {
perror ("kvm_open");
return (-1);
      }
    if (kvm_nlist (kd, nlst) < 0)
      {
perror ("kvm_nlist");
return (-1);
      }
    if (check_nlist (nlst) != 0)
      return (-1);

    /* NPROC Tuning parameter for max number of processes */
    getkstatval("unix", 0, "var", &v);
    nproc = v.v_proc;
    getkstatval("unix", 0, "sysinfo", &sysinfo);
    getkstatval("unix", 0, "vminfo", &vminfo);

    /* stash away certain offsets for later use */
    mpid_offset = nlst[X_MPID].n_value;
    maxmem_offset = nlst[X_MAXMEM].n_value;

    ncpus = get_system_misc("ncpus");

    /*
     * figure out which cpu's are installed and record the fact
     * so we know which cpu's to get info for
     */
    cpu_stats = (int *) malloc(ncpus * sizeof(int));
    n = 0;
    i = 0;
    while (n < ncpus) {
sprintf(buf, "cpu_stat%d", i);
if (kstat = kstat_lookup(kstat_ctl, "cpu_stat", i, buf)) {
     cpu_stats[n] = i;
     n++;
} i++;
    }

    /* allocate space for proc structure array and array of pointers */
    bytes = nproc * PRPSINFOSIZE;
    pbase = (struct prpsinfo *) malloc (bytes);
    pref = (struct prpsinfo **) malloc (nproc * sizeof (struct prpsinfo *));
    oldbase = (struct oldproc *) malloc (2 * nproc * sizeof (struct oldproc));


    /* Just in case ... */
    if (pbase == (struct prpsinfo *) NULL || pref == (struct prpsinfo **) NULL
|| oldbase == (struct oldproc *) NULL)
      {
fprintf (stderr, "%s: can't allocate sufficient memoryn", myname);
return (-1);
      }

    oldprocs = 2 * nproc;
    endbase = oldbase + oldprocs;
    for (op = oldbase; op < endbase; op++)
      op->oldpid = -1;

    if (!(procdir = opendir (PROCFS)))
      {
(void) fprintf (stderr, "Unable to open %sn", PROCFS);
return (-1);
      }

    if (chdir (PROCFS))
      {    /* handy for later on when we're reading it */
(void) fprintf (stderr, "Unable to chdir to %sn", PROCFS);
return (-1);
      }

    /* all done! */
    return (0);
  }


char *
format_header (register char *uname_field)
{
  register char *ptr;

  ptr = header + UNAME_START;
  while (*uname_field != '')
    *ptr++ = *uname_field++;

  return (header);
}

void
get_system_info (struct system_info *si)
{
  long avenrun[3];
  struct cpu cpu;
  cpu_stat_t cpu_stat;
  static ulong updates;
  static ulong freemem;
  static ulong maxmem;
  static ulong  kmem;
  static int phys_pages;
  static sysinfo_t new_sysinfo;
  static vminfo_t new_vminfo;
  static kmeminfo_t kmeminfo;
  static ulong used_swap;
  static ulong free_swap;
  static long cp_time[CPUSTATES];
  static long cp_old[CPUSTATES];
  static long cp_diff[CPUSTATES];
  register int j, i;
  kstat_t *kstat;
  char  buf[32];

  /* get the cp_time array */
  for (j = 0; j < CPUSTATES; j++)
    cp_time[j] = 0L;

  for (i = 0; i < ncpus; i++) {
      sprintf(buf, "cpu_stat%d", cpu_stats[i]);
      getkstatval("cpu_stat", cpu_stats[i], buf, &cpu_stat);
      for (j = 0; j < CPUSTATES-1; j++)
cp_time[j] += (long) cpu_stat.cpu_sysinfo.cpu[j];
      cp_time[CPUSTATES-2] += (long) cpu_stat.cpu_sysinfo.wait[W_IO] +
                              (long) cpu_stat.cpu_sysinfo.wait[W_PIO];
      cp_time[CPUSTATES-1] += (long) cpu_stat.cpu_sysinfo.wait[W_SWAP];
  }

  /* convert cp_time counts to percentages */
  (void) percentages (CPUSTATES, cpu_states, cp_time, cp_old, cp_diff);

  /* get mpid -- process id of last process */
  (void) getkval (mpid_offset, &(si->last_pid), sizeof (si->last_pid), "mpid");

  /* get load average array */
  avenrun[0] = get_system_misc("avenrun_1min");
  avenrun[1] = get_system_misc("avenrun_5min");
  avenrun[2] = get_system_misc("avenrun_15min");

  /* convert load averages to doubles */
  for (i = 0; i < 3; i++)
    si->load_avg[i] = loaddouble (avenrun[i]);

  getkstatval("unix", 0, "sysinfo", &new_sysinfo);
  getkstatval("unix", 0, "vminfo", &new_vminfo);
  getkstatval("unix", 0, "kmeminfo", &kmeminfo);

  /* get system wide main memory usage structure */

  updates = new_sysinfo.updates - sysinfo.updates;
  if (! updates)
      updates = 1;
  freemem = (new_vminfo.freemem - vminfo.freemem) / updates;
  used_swap = (new_vminfo.swap_resv - vminfo.swap_resv) / updates;
  free_swap = (new_vminfo.swap_avail - vminfo.swap_avail) / updates;

  phys_pages = sysconf(_SC_PHYS_PAGES);
  kmem = ((kmeminfo.km_mem[0] + kmeminfo.km_mem[1] +
   kmeminfo.km_alloc[2]) / pagesize);

  if (phys_pages > 0)
      maxmem = phys_pages - kmem;
  else
      (void) getkval (maxmem_offset, &maxmem, sizeof (maxmem), "maxmem");

  memory_stats[0] = pagetok (maxmem);
  memory_stats[1] = pagetok (kmem);
  memory_stats[2] = pagetok (freemem);
  memory_stats[3] = pagetok (used_swap);
  memory_stats[4] = pagetok (free_swap);

  sysinfo = new_sysinfo;
  vminfo = new_vminfo;

  /* set arrays and strings */
  si->cpustates = cpu_states;
  si->memory = memory_stats;
}

static struct handle handle;

caddr_t
get_process_info (
     struct system_info *si,
     struct process_select *sel,
     int (*compare) ())
{
  register int i;
  register int total_procs;
  register int active_procs;
  register struct prpsinfo **prefp;
  register struct prpsinfo *pp;

  /* these are copied out of sel for speed */
  int show_idle;
  int show_system;
  int show_uid;

  /* Get current number of processes */
  nproc = get_system_misc("nproc");

  /* read all the proc structures */
  getptable (pbase);

  /* get a pointer to the states summary array */
  si->procstates = process_states;

  /* set up flags which define what we are going to select */
  show_idle = sel->idle;
  show_system = sel->system;
  show_uid = sel->uid != -1;

  /* count up process states and get pointers to interesting procs */
  total_procs = 0;
  active_procs = 0;
  (void) memset (process_states, 0, sizeof (process_states));
  prefp = pref;

  for (pp = pbase, i = 0; i < nproc;
       i++, pp = (struct prpsinfo *) ((char *) pp + PRPSINFOSIZE))
    {
      /*
  *  Place pointers to each valid proc structure in pref[].
  *  Process slots that are actually in use have a non-zero
  *  status field.  Processes with SSYS set are system
  *  processes---these get ignored unless show_sysprocs is set.
  */
      if (pp->pr_state != 0 &&
   (show_system || ((pp->pr_flag & SSYS) == 0)))
{
   total_procs++;
   process_states[pp->pr_state]++;
   if ((!pp->pr_zomb) &&
       (show_idle || percent_cpu (pp) || (pp->pr_state == SRUN) || (pp->pr_state == SONPROC)) &&
       (!show_uid || pp->pr_uid == (uid_t) sel->uid))
     {
       *prefp++ = pp;
       active_procs++;
     }
}
    }

  /* if requested, sort the "interesting" processes */
  if (compare != NULL)
    qsort ((char *) pref, active_procs, sizeof (struct prpsinfo *), compare);

  /* remember active and total counts */
  si->p_total = total_procs;
  si->p_active = active_procs;

  /* pass back a handle */
  handle.next_proc = pref;
  handle.remaining = active_procs;
  return ((caddr_t) & handle);
}

char fmt[MAX_COLS];   /* static area where result is built */

char *
format_next_process (
        caddr_t handle,
        char *(*get_userid) ())
{
  register struct prpsinfo *pp;
  struct handle *hp;
  register long cputime;
  register double pctcpu;

  /* find and remember the next proc structure */
  hp = (struct handle *) handle;
  pp = *(hp->next_proc++);
  hp->remaining--;

  /* get the cpu usage and calculate the cpu percentages */
  cputime = pp->pr_time.tv_sec;
  pctcpu = percent_cpu (pp);

  /* format this entry */
  sprintf (fmt,
    Proc_format,
    pp->pr_pid,
    (*get_userid) (pp->pr_uid),
    pp->pr_pri - PZERO,
    pp->pr_nice - NZERO,
    format_k(pp->pr_bysize / 1024),
    format_k(pp->pr_byrssize / 1024),
    state_abbrev[pp->pr_state],
    format_time(cputime),
    weighted_cpu (pp),
    pctcpu,
    pp->pr_fname);

  /* return the result */
  return (fmt);
}

/*
* check_nlist(nlst) - checks the nlist to see if any symbols were not
*  found.  For every symbol that was not found, a one-line
*  message is printed to stderr.  The routine returns the
*  number of symbols NOT found.
*/
int
check_nlist (register struct nlist *nlst)
{
  register int i;

  /* check to see if we got ALL the symbols we requested */
  /* this will write one line to stderr for every symbol not found */

  i = 0;
  while (nlst->n_name != NULL)
    {
      if (nlst->n_type == 0)
{
   /* this one wasn't found */
   fprintf (stderr, "kernel: no symbol named `%s'n", nlst->n_name);
   i = 1;
}   nlst++;
    } return (i);
}


/*
*  getkval(offset, ptr, size, refstr) - get a value out of the kernel.
* "offset" is the byte offset into the kernel for the desired value,
*   "ptr" points to a buffer into which the value is retrieved,
*   "size" is the size of the buffer (and the object to retrieve),
*   "refstr" is a reference string used when printing error meessages,
*     if "refstr" starts with a '!', then a failure on read will not
*       be fatal (this may seem like a silly way to do things, but I
*       really didn't want the overhead of another argument).
*
*/
int
getkval (unsigned long offset,
  int *ptr,
  int size,
  char *refstr)
{
  if (kvm_read (kd, offset, (char *) ptr, size) != size)
    {
      if (*refstr == '!')
{
   return (0);
}
      else
{
   fprintf (stderr, "top: kvm_read for %s: %sn", refstr, sys_errlist[errno]);
   quit (23);
}
    }
  return (1);

}

/*
*  get_system_misc(variable) - get a misc system stat value
* "variable" is the name of the variable to get the value for
*/
int
get_system_misc(char *s)
{
    kstat_t  *kstat;
    kstat_named_t *kstat_named;
    int   n,
   i;

    if ((kstat = kstat_lookup(kstat_ctl, "unix", 0, "system_misc")) == NULL) {
perror("kstat_lookup");
return(-1);
    }
    kstat_named = (kstat_named_t *) malloc(kstat->ks_data_size);
    n = kstat->ks_ndata;
    kstat->ks_data = (void *) kstat_named;
    if (kstat_read(kstat_ctl, kstat, NULL) < 0) {
perror("kstat_read");
return(-1);
    }

    for (i = 0; i < n, strcmp(s, kstat_named[i].name); i++);

    if (i == n)
return(-1);

    n = kstat_named[i].value.ul;
    free(kstat_named);
    return(n);
}

/*
*  getkstatval(module, instance, name, ptr) - get a kernal stat value
* "module" is the name of the module containing the value
* "instance" is the instance of the module
* "name" is the name of the stat in the module
*   "ptr" points to a buffer into which the value is retrieved,
*/
int
getkstatval(char *module,
     int  instance,
     char *name,
     void *value)
{
    kstat_t *kstat;

    kstat = kstat_lookup(kstat_ctl, module, instance, name);
    if (!kstat) {
perror("kstat_lookup");
return(-1);
    }

    kstat->ks_data = value;
    if (kstat_read(kstat_ctl, kstat, NULL) < 0) {
perror("kstat_read");
return(-1);
    }

    return(0);
}

/* comparison routine for qsort */

/*
*  proc_compare - comparison function for "qsort"
* Compares the resource consumption of two processes using five
*   distinct keys.  The keys (in descending order of importance) are:
*   percent cpu, cpu ticks, state, resident set size, total virtual
*   memory usage.  The process states are ordered as follows (from least
*   to most important):  WAIT, zombie, sleep, stop, start, run.  The
*   array declaration below maps a process state index into a number
*   that reflects this ordering.
*/


unsigned char sorted_state[] =
{
  0,    /* not used  */
  3,    /* sleep  */
  6,    /* run   */
  2,    /* zombie  */
  4,    /* stop   */
  5,    /* start  */
  7,    /* run on a processor   */
  1    /* being swapped (WAIT) */
};
int
proc_compare (
        struct prpsinfo **pp1,
        struct prpsinfo **pp2)
  {
    register struct prpsinfo *p1;
    register struct prpsinfo *p2;
    register long result;
    double dresult;

    /* remove one level of indirection */
    p1 = *pp1;
    p2 = *pp2;

    /* compare percent cpu (pctcpu) */
    dresult = percent_cpu (p2) - percent_cpu (p1);
    if (dresult != 0.0)
      {
if (dresult > 0.0)
   return 1;
else
   return -1;
      }
    {
      /* use cpticks to break the tie */
      if ((result = p2->pr_time.tv_sec - p1->pr_time.tv_sec) == 0)
{
   /* use process state to break the tie */
   if ((result = (long) (sorted_state[p2->pr_state] -
    sorted_state[p1->pr_state])) == 0)
     {
       /* use priority to break the tie */
       if ((result = p2->pr_oldpri - p1->pr_oldpri) == 0)
  {
    /* use resident set size (rssize) to break the tie */
    if ((result = p2->pr_rssize - p1->pr_rssize) == 0)
      {
        /* use total memory to break the tie */
        result = (p2->pr_size - p1->pr_size);
      }
  }  }
}
    } return (result);
  }

/*
get process table
V.4 only has a linked list of processes so we want to follow that
linked list, get all the process structures, and put them in our own
table
*/
void
getptable (struct prpsinfo *baseptr)
{
  struct prpsinfo *currproc; /* pointer to current proc structure */
  int numprocs = 0;
  int i;
  struct dirent *direntp;
  struct oldproc *op;
  static struct timeval lasttime =
  {0, 0};
  struct timeval thistime;
  double timediff;
  double alpha, beta;
  struct oldproc *endbase;

  gettimeofday (&thistime);
  /*
   * To avoid divides, we keep times in nanoseconds.  This is
   * scaled by 1e7 rather than 1e9 so that when we divide we
   * get percent.
   */
  if (lasttime.tv_sec)
    timediff = ((double) thistime.tv_sec * 1.0e7 +
  ((double) thistime.tv_usec * 10.0)) -
      ((double) lasttime.tv_sec * 1.0e7 +
       ((double) lasttime.tv_usec * 10.0));
  else
    timediff = 1.0e7;

  /*
     * constants for exponential average.  avg = alpha * new + beta * avg
     * The goal is 50% decay in 30 sec.  However if the sample period
     * is greater than 30 sec, there's not a lot we can do.
     */
  if (timediff < 30.0e7)
    {
      alpha = 0.5 * (timediff / 30.0e7);
      beta = 1.0 - alpha;
    }
  else
    {
      alpha = 0.5;
      beta = 0.5;
    }

  endbase = oldbase + oldprocs;
  currproc = baseptr;

  for (rewinddir (procdir); (direntp = readdir (procdir));)
    {
      int fd;

      if ((fd = open (direntp->d_name, O_RDONLY)) < 0)
continue;

      if (ioctl (fd, PIOCPSINFO, currproc) < 0)
{
   (void) close (fd);
   continue;
}

      /*
       * SVr4 doesn't keep track of CPU% in the kernel, so we have
       * to do our own.  See if we've heard of this process before.
       * If so, compute % based on CPU since last time.
       */
      op = oldbase + HASH (currproc->pr_pid);
      while (1)
{
   if (op->oldpid == -1) /* not there */
     break;
   if (op->oldpid == currproc->pr_pid)
     {   /* found old data */
       percent_cpu (currproc) =
  ((currproc->pr_time.tv_sec * 1.0e9 +
    currproc->pr_time.tv_nsec)
   - op->oldtime) / timediff;
       weighted_cpu (currproc) =
  op->oldpct * beta + percent_cpu (currproc) * alpha;

       break;
     }
   op++;   /* try next entry in hash table */
   if (op == endbase) /* table wrapped around */
     op = oldbase;
}

      /* Otherwise, it's new, so use all of its CPU time */
      if (op->oldpid == -1)
{
   if (lasttime.tv_sec)
     {
       percent_cpu (currproc) =
  (currproc->pr_time.tv_sec * 1.0e9 +
   currproc->pr_time.tv_nsec) / timediff;
       weighted_cpu (currproc) =
  percent_cpu (currproc);
     }
   else
     {   /* first screen -- no difference is possible */
       percent_cpu (currproc) = 0.0;
       weighted_cpu (currproc) = 0.0;
     }
}

      numprocs++;
      currproc = (struct prpsinfo *) ((char *) currproc + PRPSINFOSIZE);
      (void) close (fd);
    }

  if (nproc != numprocs)
    nproc = numprocs;

  /*
   * Save current CPU time for next time around
   * For the moment recreate the hash table each time, as the code
   * is easier that way.
   */
  oldprocs = 2 * nproc;
  endbase = oldbase + oldprocs;
  for (op = oldbase; op < endbase; op++)
    op->oldpid = -1;
  for (i = 0, currproc = baseptr;
       i < nproc;
     i++, currproc = (struct prpsinfo *) ((char *) currproc + PRPSINFOSIZE))
    {
      /* find an empty spot */
      op = oldbase + HASH (currproc->pr_pid);
      while (1)
{
   if (op->oldpid == -1)
     break;
   op++;
   if (op == endbase)
     op = oldbase;
}
      op->oldpid = currproc->pr_pid;
      op->oldtime = (currproc->pr_time.tv_sec * 1.0e9 +
       currproc->pr_time.tv_nsec);
      op->oldpct = weighted_cpu (currproc);
    } lasttime = thistime;
}

/*
* proc_owner(pid) - returns the uid that owns process "pid", or -1 if
*              the process does not exist.
*              It is EXTREMLY IMPORTANT that this function work correctly.
*              If top runs setuid root (as in SVR4), then this function
*              is the only thing that stands in the way of a serious
*              security problem.  It validates requests for the "kill"
*              and "renice" commands.
*/
uid_t
proc_owner (pid_t pid)
{
  register struct prpsinfo *p;
  int i;
  for (i = 0, p = pbase; i < nproc;
       i++, p = (struct prpsinfo *) ((char *) p + PRPSINFOSIZE))
    if (p->pr_pid == pid)
      return (p->pr_uid);
  return (-1);
}

int
setpriority (int dummy, int who, int niceval)
{
  int scale;
  int prio;
  pcinfo_t pcinfo;
  pcparms_t pcparms;
  tsparms_t *tsparms;

  strcpy (pcinfo.pc_clname, "TS");
  if (priocntl (0, 0, PC_GETCID, (caddr_t) & pcinfo) == -1)
    return (-1);

  prio = niceval;
  if (prio > PRIO_MAX)
    prio = PRIO_MAX;
  else if (prio < PRIO_MIN)
    prio = PRIO_MIN;

  tsparms = (tsparms_t *) pcparms.pc_clparms;
  scale = ((tsinfo_t *) pcinfo.pc_clinfo)->ts_maxupri;
  tsparms->ts_uprilim = tsparms->ts_upri = -(scale * prio) / 20;
  pcparms.pc_cid = pcinfo.pc_cid;

  if (priocntl (P_PID, who, PC_SETPARMS, (caddr_t) & pcparms) == -1)
    return (-1);

  return (0);
}





143   [Delphi] [소스] 델파이 프로그램 소스파일에서 한글 문장 추출  김영대 2005/02/01 10508 1787
142   [Delphi] [소스] 데스크탑의 일부 영역을 고정적으로 차지하는 어플리케이션  김영대 2004/06/19 7099 1619
141   [Delphi] [소스] 다기능 DBGrid (복수 Title, 자동정렬..)  김영대 2003/03/12 9086 1792
140   [Delphi] [소스] 다국어를 지원하는 응용 프로그램을 위한 콤포넌트  김영대 2005/02/01 7964 1631
139   [Delphi] [소스] 네트워크 환경의 TCP/IP 등록정보 읽어오기  김영대 2003/03/11 7020 1776
138   [Delphi] [소스] 내 PC의 IP 구하기 예제  김영대 2003/03/12 7447 1631
137   [컴퓨터 전공] [소스] 계산기를 위한 Lex & Yacc  김영대 2003/03/15 10377 1697
136   [네트워크/보안] [소스] 간단한 채팅 클라이언트/서버  김영대 2003/03/13 11890 1806
135   [Delphi] [소스] 간단한 계산기 프로그램 소스  김영대 2003/03/12 6997 1483
134   [컴퓨터 전공] [소스] Windows RLE(BMP) Encoder  김영대 2003/03/18 8164 1425
133   [Delphi] [소스] Windows Management Instrumentation (WMI)  김영대 2004/07/24 9884 1956
132   [Delphi] [소스] UNIX 서버의 현재시간 읽어오기  김영대 2003/03/11 7459 1927
131   [Delphi] [소스] UNIX tail 과 같은 파일 변경 감시 프로그램  김영대 2004/09/04 8628 1696
130   [Delphi] [소스] tray icon 예제소스  김영대 2003/03/12 8109 1583
129   [컴퓨터 전공] [소스] Top-down parsing by Recursive-Descent 을 이용한 계산기 MASM 어셈블리 생성기  김영대 2003/07/11 8014 1733
128   [Unix/Linux] [소스] top for System V Release 4, Intel or Sparc CPU  김영대 2004/02/20 9760 1217
  [Unix/Linux] [소스] top for SunOS 5.x (Solaris 2.x)  김영대 2004/02/20 14752 1261
126   [Delphi] [소스] TMSNPopUp v.5.0 수정 콤포넌트  김영대 2004/11/16 10667 2010
125   [Delphi] [소스] Text(*.csv, *.txt) 파일을 DB 로 올리기  김영대 2003/03/12 9245 1609
124   [Delphi] [소스] String을 MS-WORD 로 보내는 콤포넌트  김영대 2003/03/19 6481 1524

[1][2] 3 [4][5][6][7][8][9][10]
 

Copyright 1999-2020 Zeroboard / skin by zero