home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / top / kernel.c < prev    next >
C/C++ Source or Header  |  1992-02-01  |  4KB  |  217 lines

  1. /*
  2.  *  Top - a top users display for Berkeley Unix
  3.  *  
  4.  *  This file contains all the routines that retrieve values from
  5.  *  kernel and user memory.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #if defined(FOUR_ONE) || defined(pyr)
  10. #include <sys/pte.h>
  11. #else
  12. #include <machine/pte.h>
  13. #endif
  14. #ifdef sunos4
  15. #include <kvm.h>
  16. #include <fcntl.h>
  17. #endif
  18. #include <sys/param.h>
  19. #include <sys/dir.h>
  20. #include <sys/user.h>
  21. #ifdef scs
  22. # define FLOAT        /* for pcrcpu in proc.h */
  23. # include <sys/vm.h>    /* for struct spt */
  24. #endif
  25. #include <sys/proc.h>
  26.  
  27. #include "top.local.h"
  28.  
  29. /* useful externals */
  30. extern int errno;
  31. extern char *sys_errlist[];
  32.  
  33. long lseek();
  34.  
  35. #ifdef sunos4
  36. /* exported to top.c */
  37. kvm_t *kd;
  38. #else
  39. static int kmem = -1;
  40. static int mem = -1;
  41. #endif
  42.  
  43. init_kernel()
  44. {
  45.     /* open kernel memory */
  46. #ifdef sunos4
  47.     if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "top")) == NULL)
  48.     {
  49.       exit(20);
  50.     }
  51. #else
  52.     if ((kmem = open(KMEM, 0)) < 0)
  53.     {
  54.     perror(KMEM);
  55.     exit(20);
  56.     }
  57.     if ((mem = open(MEM, 0)) < 0)
  58.     {
  59.     perror(MEM);
  60.     exit(21);
  61.     }
  62. #endif
  63. }
  64.  
  65. #ifndef scs        /* getu is not needed on a Symbolics */
  66.  
  67. /*
  68.  *  getu(p, u) - get the user structure for the process whose proc structure
  69.  *    is pointed to by p.  The user structure is put in the buffer pointed
  70.  *    to by u.  Return 0 if successful, -1 on failure (such as the process
  71.  *    being swapped out).
  72.  */
  73.  
  74. getu(p, u)
  75.  
  76. register struct proc *p;
  77. struct user *u;
  78.  
  79. {
  80. #ifdef sunos4
  81.     register struct user *lu;
  82.  
  83.     lu = kvm_getu(kd, p);
  84.     if (lu == NULL)
  85.     return(-1);
  86.     else
  87.     {
  88.     *u = *lu;
  89.     return(0);
  90.     }
  91. #else
  92.     struct pte uptes[UPAGES];
  93.     register caddr_t upage;
  94.     register struct pte *pte;
  95.     register nbytes, n;
  96.  
  97.     /*
  98.      *  Check if the process is currently loaded or swapped out.  The way we
  99.      *  get the u area is totally different for the two cases.  For this
  100.      *  application, we just don't bother if the process is swapped out.
  101.      */
  102.     if ((p->p_flag & SLOAD) == 0)
  103.     {
  104.     return(-1);
  105.     }
  106.  
  107.     /*
  108.      *  Process is currently in memory, we hope!
  109.      */
  110.     if (!getkval((unsigned long)p->p_addr, (int *)uptes, sizeof(uptes),
  111.         "!p->p_addr"))
  112.     {
  113.     /* we can't seem to get to it, so pretend it's swapped out */
  114.     return(-1);
  115.     } 
  116.     upage = (caddr_t)u;
  117.     pte = uptes;
  118.     for (nbytes = sizeof(struct user); nbytes > 0; nbytes -= NBPG)
  119.     {
  120.         (void) lseek(mem, (long)(pte++->pg_pfnum * NBPG), 0);
  121.     n = MIN(nbytes, NBPG);
  122.     if (read(mem, upage, n) != n)
  123.     {
  124.         /* we can't seem to get to it, so pretend it's swapped out */
  125.         return(-1);
  126.     }
  127.     upage += n;
  128.     }
  129.     return(0);
  130. #endif !sunos4
  131. }
  132. #endif !scs
  133.  
  134. /*
  135.  *  getkval(offset, ptr, size, refstr) - get a value out of the kernel.
  136.  *    "offset" is the byte offset into the kernel for the desired value,
  137.  *      "ptr" points to a buffer into which the value is retrieved,
  138.  *      "size" is the size of the buffer (and the object to retrieve),
  139.  *      "refstr" is a reference string used when printing error meessages,
  140.  *        if "refstr" starts with a '!', then a failure on read will not
  141.  *          be fatal (this may seem like a silly way to do things, but I
  142.  *          really didn't want the overhead of another argument).
  143.  *      
  144.  */
  145.  
  146. getkval(offset, ptr, size, refstr)
  147.  
  148. unsigned long offset;
  149. int *ptr;
  150. int size;
  151. char *refstr;
  152.  
  153. {
  154. #ifdef sunos4
  155.     if (kvm_read(kd, offset, ptr, size) != size)
  156.     {
  157.     if (*refstr == '!')
  158.     {
  159.         return(0);
  160.     }
  161.     else
  162.     {
  163.         fprintf(stderr, "top: kvm_read for %s: %s\n",
  164.         refstr, sys_errlist[errno]);
  165.         quit(23);
  166.     }
  167.     }
  168.     return(1);
  169.     
  170. #else
  171.     if (lseek(kmem, (long)offset, 0) == -1)
  172.     {
  173.     if (*refstr == '!')
  174.     {
  175.         refstr++;
  176.     }
  177.     fprintf(stderr, "%s: lseek to %s: %s\n",
  178.         KMEM, refstr, sys_errlist[errno]);
  179.     quit(22);
  180.     }
  181.     if (read(kmem, (char *)ptr, size) == -1)
  182.     {
  183.     if (*refstr == '!')
  184.     {
  185.         /* we lost the race with the kernel, process isn't in memory */
  186.         return(0);
  187.     } 
  188.     else 
  189.     {
  190.         fprintf(stderr, "%s: reading %s: %s\n",
  191.         KMEM, refstr, sys_errlist[errno]);
  192.         quit(23);
  193.     }
  194.     }
  195.     return(1);
  196. #endif !sunos4
  197. }
  198.  
  199. #ifdef scs
  200. void
  201. get_spt(spti, sptp)
  202.  
  203. int       spti;
  204. struct spt *sptp;
  205.  
  206. {
  207.     extern struct spt *spt;        /* defined in top.c */
  208.  
  209.     /* Let's get tricky, shall we?  *spt is a pointer in kernel space;
  210.      * we can use it in a getkval() call, but we can't dereference it
  211.      * directly.  However, C's pointer arithmetic will still work, even
  212.      * though we aren't going to use the pointer as a pointer...
  213.      */
  214.     getkval(spt + spti, sptp, sizeof(struct spt), "spt");
  215. }
  216. #endif scs
  217.