home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / finger / part05 / readpr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-03  |  9.3 KB  |  337 lines

  1. /*
  2.  * readpr.c -- read process table
  3.  *
  4.  * Copyright (C) 1986, 1990  Philip L. Budne
  5.  *
  6.  * This file is part of "Phil's Finger Program".
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 1, or (at your option)
  11.  * any later version.
  12.  *
  13.  */
  14.  
  15. # ifndef lint
  16. static char *rcsid = "$Id: readpr.c,v 3.0 90/07/06 13:11:38 budd Rel $";
  17. # endif /* lint not defined */
  18.  
  19. # include "finger.h"
  20. # include "waitstate.h"
  21. # ifndef Umax
  22.  
  23. # include <stdio.h>
  24. # include "ustruct.h"
  25.  
  26. # ifdef USG
  27. # include <sys/var.h>
  28. # endif /* USG defined */
  29.  
  30. # ifndef SIGHUP
  31. # include <signal.h>
  32. # endif /* SIGHUP not defined */
  33.  
  34. # include "pr.h"
  35. # include "kmem.h"
  36. # include "info.h"            /* after finger.h */
  37. # include "args.h"            /* for debugsw */
  38.  
  39. /* # define DEBUG_READPR        /* dump all pr's */
  40.  
  41. # ifndef UTMP_NO_HOST
  42. # define MUST_HAVE_TTY            /* run a bit faster */
  43. # endif /* UTMP_NO_HOST not defined */
  44.  
  45. extern struct info I;            /* namelist values from names.c */
  46. extern struct user *ustruct();        /* from ustruct.c */
  47. extern void u_cleanup();        /* from ustruct.c */
  48.  
  49. extern FTYPE kmem;            /* fd for /dev/kmem */
  50.                     /* (more under SunOS 4.0) */
  51. # if SunOS < 400
  52. extern FTYPE mem;            /* fd for /dev/mem */
  53. extern FTYPE swap;            /* fd for /dev/drum */
  54.                     /* from kmem.c */
  55. # endif /* SunOS < 400 */
  56.  
  57. FORWARD LOCAL enum sig istate();
  58.  
  59. LOCAL int nproc;            /* kernel nproc */
  60. LOCAL struct proc *aproc;        /* kernel virt addr of process table */
  61.  
  62. /*
  63.  * readpr finds and reads in the array pr, containing the interesting
  64.  * parts of the proc and user tables for each live process.
  65.  */
  66.  
  67. # ifdef AIX3
  68. # define MAXPROC 512
  69.  
  70. GLOBAL struct pr *readpr() {
  71.     int i, n;
  72.     struct pr *prvec;
  73.     struct procinfo pivec[MAXPROC];
  74.     register struct pr *prp;
  75.     register struct procinfo *pip;
  76.  
  77.     n = getproc( pivec, MAXPROC, sizeof( struct procinfo ) );
  78.     if( n < 1 ) {
  79.         /* Check errno, report of MAXPROC too small!!! */
  80.     return( NULL );
  81.     }
  82.  
  83.     prvec = (struct pr *) calloc( n+1, sizeof( struct pr ) );
  84.     if( prvec == NULL )
  85.     return( NULL );
  86.  
  87.     prp = prvec;
  88.     for( i = 0, pip = pivec; i < n; i++, pip++ ) {
  89.     struct userinfo ui;
  90.  
  91.     if( pip->pi_stat == 0 )
  92.         continue;
  93.  
  94.     if( getuser( pip, sizeof( struct procinfo ),
  95.             &ui,  sizeof( struct userinfo ) ) < 0 )
  96.         continue;
  97.  
  98.     prp->pr_uid = pip->pi_uid;
  99.     prp->pr_pid = pip->pi_pid;
  100.     prp->pr_ppid = pip->pi_ppid;
  101.     prp->pr_pgrp = pip->pi_pgrp;
  102.     prp->pr_stat = pip->pi_stat;
  103.     prp->pr_flag = pip->pi_flag;
  104.     prp->pr_wchan = pip->pi_wchan;
  105.  
  106.     prp->pr_ttyp = ui.ui_ttyp;
  107.     prp->pr_ttyd = ui.ui_ttyd + ui.ui_ttympx;
  108.  
  109.     strzcpy(prp->pr_cmd, ui.ui_comm, sizeof( ui.ui_comm ) );
  110. # ifdef DEBUG_READPR
  111.     dumppr( prp );
  112. # endif /* DEBUG_READPR defined */
  113.     prp++;
  114.     }
  115.     prp->pr_stat = 0;            /* mark end */
  116.  
  117. # ifdef DEBUGSW
  118.     if( sw_debug )
  119.     printf("read %d processes\n", prp - prvec );
  120. # endif /* DEBUGSW defined */
  121.  
  122.     /* realloc prvec to size? */
  123.     return( prvec );
  124. }
  125.  
  126. # else  /* AIX3 not defined */
  127.  
  128. GLOBAL struct pr *readpr() {
  129.     register struct pr *prp;        /* current pr entry */
  130.     register int i;            /* loop index */
  131.     struct user *upp;            /* pointer to upage(s) */
  132.     struct proc *mpp;            /* ptr to current process */
  133.     struct pr *prvec;
  134.     struct proc *allproc;        /* whole process table */
  135. # ifdef USG
  136.     struct var v;
  137. # endif /* USG defined */
  138. # if SunOS >= 410
  139.     struct sess sess;
  140. # endif /* SunOS >= 410 */
  141.  
  142.     if( !ini_kmem() )            /* initialize /dev/kmem etc. */
  143.     return( NULL );
  144.  
  145. # ifdef USG
  146.     KMEMREAD(I.info_v, &v, sizeof( v ) ); /* var struct */
  147.     nproc = v.v_proc;            /* size of proc table */
  148.     aproc = (struct proc *) I.info_proc; /* addr of proc table */
  149. # else  /* USG not defined */
  150.     KMEMREAD(I.info_nproc, &nproc, sizeof( nproc )); /* size of proc tbl */
  151.     KMEMREAD(I.info_proc,  &aproc, sizeof( aproc )); /* addr of proc tbl */
  152. # endif /* USG not defined */
  153.  
  154. # ifdef DEBUG_READPR
  155.     printf("nproc %d aproc %#x\n", nproc, aproc );
  156. # endif /* DEBUG_READPR defined */
  157.  
  158.     prvec = (struct pr *)calloc(nproc+1, sizeof(struct pr));/* allocate tbl */
  159.     if( prvec == NULL )
  160.     return( NULL );
  161.  
  162.     allproc = (struct proc *) calloc(nproc, sizeof( struct proc ) );
  163.     KMEMREAD(aproc, allproc, nproc * sizeof( struct proc ) );
  164.     mpp = allproc;
  165.  
  166.     prp = prvec;            /* pointer to dest block */
  167.     for( i = 0; i < nproc; i++, mpp++ ) { /* for all processes */
  168.     if( mpp->p_stat == 0 || mpp->p_stat == SZOMB ) /* a zombie or worse? */
  169.         continue;            /* forget it */
  170.  
  171. # ifdef SSYS
  172.     if( mpp->p_flag & SSYS )    /* swapper or pager? */
  173.         continue;            /* flush */
  174. # endif /* SSYS defined */
  175.  
  176. # ifdef SWEXIT
  177.     if( mpp->p_flag & SWEXIT )    /* exiting? */
  178.         continue;            /* nevermind. */
  179. # endif /* SWEXIT defined */
  180.  
  181. # if defined(MUST_HAVE_TTY) && defined(P_TTYP)
  182.     /* avoid fetching ustruct needlessly */
  183.     if( mpp->p_ttyp == NULL )    /* no terminal pointer? */
  184.         continue;
  185. # endif /* defined(MUST_HAVE_TTY) && defined(P_TTYP) */
  186.  
  187. # if SunOS >= 410
  188.     if( mpp->p_sessp == NULL ||
  189.        !KMEMREAD( (long)mpp->p_sessp, (char *)&sess, sizeof(sess) ) ) {
  190. # ifdef MUST_HAVE_TTY
  191.         continue;
  192. # else  /* MUST_HAVE_TTY not defined */
  193.         sess.s_ttyp = NULL;
  194. # endif /* MUST_HAVE_TTY not defined */
  195.     } /* no session or kmem read failed */
  196. # endif /* SunOS >= 410 */
  197.  
  198.     if( (upp = ustruct( mpp )) == NULL ) /* get ustruct? */
  199.         continue;            /* no point. */
  200.  
  201. # ifdef DEBUGSW
  202.     if( sw_debug && ((unsigned)upp->u_procp) != ((unsigned)(aproc + i)) )
  203.        printf("%%Funny u struct for pid %d u_procp %#x != %#x\n",
  204.           mpp->p_pid, upp->u_procp, (aproc + i) );
  205. # endif /* DEBUGSW defined */
  206.  
  207.     /*
  208.      * WISH:
  209.      * check for master /etc/inetd /etc/rlogind etc???  (as a way to
  210.      * establish root of a process tree and avoid stray background
  211.      * processes on that tty) and keep only descendants thereof.
  212.      */
  213.  
  214. # if 0 /* since we already have ustruct, just keep it! */
  215. # if defined(MUST_HAVE_TTY) && !defined(P_TTYP) && SunOS < 410
  216.     if( upp->u_ttyp == NULL )    /* no terminal pointer? */
  217.         continue;
  218. # endif /* defined(MUST_HAVE_TTY) && !defined(P_TTYP) && SunOS < 410 */
  219. # endif /* 0 */
  220.  
  221.     /* save the interesting parts */
  222.     prp->pr_uid = mpp->p_uid;    /* user id */
  223.     prp->pr_pid = mpp->p_pid;    /* pid */
  224.     prp->pr_ppid = mpp->p_ppid;    /* parent pid */
  225.     prp->pr_pgrp = mpp->p_pgrp;    /* process group leader pid */
  226.     prp->pr_stat = mpp->p_stat;    /* state (1..6) */
  227.     prp->pr_flag = mpp->p_flag;    /* flags (esp swap) */
  228.     prp->pr_wchan = mpp->p_wchan;    /* wait address */
  229.  
  230. # if SunOS >= 410
  231.     prp->pr_ttyp = sess.s_ttyp;
  232.     prp->pr_ttyd = sess.s_ttyd;
  233. # else  /* not SunOS >= 410 */
  234. # ifdef P_TTYP
  235.     prp->pr_ttyp = mpp->p_ttyp;    /* pointer to tty structure */
  236. # else  /* P_TTYP not defined */
  237.     prp->pr_ttyp = upp->u_ttyp;    /* pointer to tty structure or tpg */
  238. # endif /* P_TTYP not defined */
  239.     prp->pr_ttyd = upp->u_ttyd;    /* device number */
  240. # endif /* not SunOS >= 410 */
  241.     prp->pr_hup  = istate( upp->u_signal[SIGHUP] );
  242.     prp->pr_intr = istate( upp->u_signal[SIGINT] );
  243.     prp->pr_quit = istate( upp->u_signal[SIGQUIT]);
  244.     /* what you've all been waiting for... */
  245.     strzcpy(prp->pr_cmd, upp->u_comm, sizeof( upp->u_comm ) );
  246.  
  247. # ifdef DEBUG_READPR
  248.     dumppr( prp );
  249. # endif /* DEBUG_READPR defined */
  250.     prp++;
  251.     } /* for i */
  252.     prp->pr_stat = 0;            /* mark end */
  253.     
  254.     /* WISH: realloc to shorten prvec? */
  255.  
  256.     free( allproc );            /* free copy of process table */
  257.     u_cleanup();            /* cleanup ustruct reader */
  258.  
  259. # ifdef DEBUGSW
  260.     if( sw_debug )
  261.     printf("read %d processes\n", prp - prvec );
  262. # endif /* DEBUGSW defined */
  263.  
  264.     return( prvec );
  265. } /* readpr */
  266.  
  267. LOCAL enum sig istate( x )        /* return signal handler state */
  268. # ifdef VOIDSIG
  269.     void (*x)();
  270. # else  /* VOIDSIG not defined */
  271.     int (*x)();
  272. # endif /* VOIDSIG not defined */
  273. {
  274.     if( x == SIG_DFL )
  275.         return( S_DEFAULT );        /* no handler */
  276.     else if( x == SIG_IGN )
  277.         return( S_IGNORE );        /* ignores interrupts */
  278. # ifdef SIG_HOLD
  279.     else if( x == SIG_HOLD )
  280.         return( S_HOLD );        /* interrupt held? */
  281. # endif /* SIG_HOLD defined */
  282.     else
  283.     return( S_CATCH );        /* has handler */
  284. } /* istate */
  285.  
  286. # endif /* AIX3 not defined */
  287.  
  288. GLOBAL waitstate_t waitstate( prp )    /* look at process wait states */
  289.     struct pr *prp;
  290. {
  291. # ifndef SHORT_TTYP            /* non-streams tty drivers... */
  292.     register struct tty *t;
  293. # endif /* SHORT_TTYP not defined */
  294.     register caddr_t w;
  295.  
  296.     w = prp->pr_wchan;            /* get wait addr */
  297.     if( w == (caddr_t) 0 )        /* no wait? */
  298.     return( WS_RU );        /* runable */
  299.  
  300. # ifndef SHORT_TTYP            /* non-streams tty drivers... */
  301.     t = prp->pr_ttyp;            /* get tty pointer */
  302.  
  303.     if( w == (caddr_t) &t->t_rawq )    /* input wait */
  304.     return( WS_TI );
  305.     if( w == (caddr_t) &t->t_outq )    /* output wait */
  306.     return( WS_TO );
  307.     if( w >= (caddr_t) t && w < (caddr_t) (t+1) ) /* other terminal wait */
  308.     return( WS_TW );
  309. # endif /* SHORT_TTYP not defined */
  310.  
  311. # ifdef USG
  312. # ifdef STREAMS
  313.     if( w == (caddr_t) I.info_pollwait ) /* poll(2) */
  314.     return( WS_SE );
  315. # endif /* STREAMS defined */
  316. # else  /* USG not defined */
  317.     if( w == (caddr_t) I.info_selwait )    /* select(2) */
  318.     return( WS_SE );
  319. # endif /* USG not defined */
  320. # if SunOS < 410
  321.     if( w == (caddr_t) I.info_u )    /* pause(2) */
  322.     return( WS_PA );
  323. # endif /* SunOS < 410 */
  324.     if( w >= (caddr_t) aproc && w <= (caddr_t) (aproc+nproc) ) /* wait(2)*/
  325.     return( WS_WA );
  326.  
  327.     return( WS_SL );            /* something else */
  328. } /* waitstate */
  329. # endif /* Umax not defined */
  330.  
  331.  
  332. /*
  333.  * Local variables:
  334.  * comment-column: 40
  335.  * End:
  336.  */
  337.