home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume23 / sps2 / part01 / waitingfor.c < prev   
C/C++ Source or Header  |  1991-01-08  |  10KB  |  349 lines

  1. # ifndef lint
  2. static char SccsId[] =  "@(#)waitingfor.c    1.5\t8/6/90" ;
  3. # endif
  4.  
  5. # include        "sps.h"
  6. # ifndef SUNOS40
  7. # include        <h/text.h>
  8. # endif SUNOS40
  9.  
  10. # ifdef NFS
  11. #  ifdef DEC3100
  12. #   include        <h/gnode.h>
  13. #   include        <h/inode.h>
  14. #  else DEC3100
  15. #   include        <h/vnode.h>
  16. #   include        <ufs/inode.h>
  17. # endif DEC3100
  18. # else
  19. #  include        <h/inode.h>
  20. # endif NFS
  21.  
  22. # include        <h/ioctl.h>
  23. # ifdef SUNOS40
  24. #  include        <h/stream.h>
  25. #  include        <h/tty.h>
  26. #  include        <h/ptyvar.h>
  27. # else SUNOS40
  28. #  include        <h/tty.h>
  29. # endif SUNOS40
  30.  
  31. # include        <h/buf.h>
  32. # ifdef BSD42
  33. #  ifdef NFS
  34. #   ifndef NOQUOTA
  35. #    ifdef DEC3100
  36. #     include        <h/quota.h>
  37. #    else
  38. #     include        <ufs/quota.h>
  39. #    endif DEC3100
  40. #   endif NOQUOTA
  41. #  else NFS
  42. #   include        <h/quota.h>
  43. #  endif NFS
  44. # include        <h/mbuf.h>
  45. # include        <h/socket.h>
  46. # include        <h/socketvar.h>
  47. # endif BSD42
  48.  
  49. /* 1 if `w' is in the address range defined by `a1' and `a2' ... */
  50. # define        INRANGE( w, a1, a2 ) \
  51.             ( (caddr_t)(a1) <= (w) && (w) < (caddr_t)(a2) )
  52.  
  53. /* NFS changes incorporated by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
  54.  
  55. /* WAITINGFOR - Determine what a process is waiting for and describe it. */
  56. char    *waitingfor ( p )
  57.  
  58. struct process                  *p ;
  59.  
  60. {
  61.     register caddr_t        w ;
  62.     register struct ttyline *lp ;
  63.     register struct symbol  *s ;
  64.     register char           *cp ;
  65. # ifdef BSD42
  66.     struct socket           sc ;
  67. # endif
  68.     int            rc ;
  69.     static char             wbuf[ 8 ] ;
  70.     extern struct info      Info ;
  71.     extern struct symbol    Symbollist[] ;
  72.     char                    *sprintf() ;
  73. # ifdef SUNOS40
  74.     char                    *gettty() ;
  75. # endif
  76.  
  77.     w = p->pr_p.p_wchan ;
  78.     if ( !w )
  79.         return ( "null" ) ;
  80.     /* Waiting for a child process, alternatively in a vfork() ? */
  81.     if ( INRANGE( w, Info.i_proc0, &Info.i_proc0[ Info.i_nproc ] ) )
  82.         return ( p->pr_p.p_flag & SNOVM ? "vfork" : "child" ) ;
  83. # ifndef SUNOS40
  84.     /* Waiting for a page to be brought in ? */
  85.     if ( INRANGE( w, Info.i_swbuf0, &Info.i_swbuf0[ Info.i_nswbuf ] ) )
  86.         return ( "swap" ) ;
  87.     /* Waiting for discio through a block device to complete ? */
  88.     if ( INRANGE( w, Info.i_buf0, &Info.i_buf0[ Info.i_nbuf ] ) )
  89.         /* SHOULD ACTUALLY READ AS "blkio" BUT "discio" IS WHAT
  90.            IS GENERALLY MEANT HERE. */
  91.         return ( "discio" ) ;
  92.     /* Waiting for a text page to be brought in ? */
  93.     if ( INRANGE( w, Info.i_text0, &Info.i_text0[ Info.i_ntext ] ) )
  94.         return ( "swtext" ) ;
  95. # endif SUNOS40
  96.  
  97. # ifdef BSD42
  98. #  ifndef NOQUOTA
  99.     /* Waiting for an event associated with the quota system ? */
  100.     if ( INRANGE( w, Info.i_quota0, &Info.i_quota0[ Info.i_nquota ] ) )
  101.         return ( "quota" ) ;
  102. #  endif NOQUOTA
  103. # endif BSD42
  104.  
  105. # ifndef SUNOS41
  106.          /* Sorry, I don't know how to do this...
  107.           * I kinda think that SunOS 4.1 allocates inode
  108.           * buffer entries dynamically.  Maybe it could be
  109.           * possible to read in all "struct file"s and
  110.           * compare each file.f_data to the wait channel.    ++sja
  111.           */
  112.     /* Waiting for an inode ? */
  113.     if ( INRANGE( w, Info.i_inode0, &Info.i_inode0[ Info.i_ninode ] ) )
  114. #  ifdef ULTRIX20
  115.         switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct gnode ))
  116. #  else
  117.         switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct inode ))
  118. #  endif ULTRIX20
  119.         {
  120. #  ifdef BSD42
  121. #   ifdef NFS
  122.             case (int)&((struct inode*)0)->i_vnode.v_exlockc :
  123.                 /* Exclusive lock on this inode */
  124.                 return ( "exlock" ) ;
  125.             case (int)&((struct inode*)0)->i_vnode.v_shlockc :
  126.                 /* Shared lock on this inode */
  127.                 return ( "shlock" ) ;
  128. #   else NFS
  129. #    ifdef ULTRIX20
  130. #     ifndef DEC3100
  131.             /* Compile this code with gcc if you want to run it
  132.                properly.  The DEC compiler can't handle this. */
  133.             case (int)&((struct gnode*)0)->g_exlockc :
  134.                 /* Exclusive lock on this inode */
  135.                 return ( "exlock" ) ;
  136.             case (int)&((struct gnode*)0)->g_shlockc :
  137.                 /* Shared lock on this inode */
  138.                 return ( "shlock" ) ;
  139.             case (int)&((struct gnode*)0)->g_frcnt :
  140.                 /* Open fifo with no readers */
  141.                 return ( "wfifo" ) ;
  142.             case (int)&((struct gnode*)0)->g_fwcnt :
  143.                 /* Open fifo with no writers */
  144.                 return ( "rfifo" ) ;
  145. #     endif DEC3100
  146. #    else ULTRIX20
  147.             case (int)&((struct inode*)0)->i_exlockc :
  148.                 /* Exclusive lock on this inode */
  149.                 return ( "exlock" ) ;
  150.             case (int)&((struct inode*)0)->i_shlockc :
  151.                 /* Shared lock on this inode */
  152.                 return ( "shlock" ) ;
  153. #    endif ULTRIX20
  154. #   endif NFS
  155. #  else BSD42 
  156.             case 1 :
  157.                 return ( "wpipe" ) ;
  158.             case 2 :
  159.                 return ( "rpipe" ) ;
  160.             case (int)&((struct inode*)0)->i_un.i_group.g_datq :
  161.                 return ( "rmux" ) ;
  162. #  endif BSD42
  163.             default :
  164.                 /* Inode probably locked */
  165.                 return ( "inode" ) ;
  166.         }
  167. # endif SUNOS41
  168.  
  169. # if defined(BSD42) && (defined(SUNOS40) || defined(NMBCLUSTERS))
  170.     /* Waiting for a structure inside an mbuf ? If so, try to find why */
  171. #  ifdef SUNOS40
  172.     if ( INRANGE( w, Info.i_mbutl,
  173.     &Info.i_mbutl[ MBPOOLBYTES / sizeof( struct mbuf ) ] ) )
  174. #  else
  175.     if ( INRANGE( w, Info.i_mbutl,
  176.     &Info.i_mbutl[ NMBCLUSTERS * CLBYTES / sizeof( struct mbuf ) ] ) )
  177. #  endif SUNOS40
  178.         switch ( ((int)w - (int)Info.i_mbutl) % sizeof( struct mbuf )
  179.             - (int)&((struct mbuf*)0)->m_dat[0] )
  180.         {
  181.             case (int)&((struct socket*)0)->so_timeo :
  182.                 /* Socket timeout event - Guess why */
  183.                 rc = getsocket( (struct socket*)(w
  184.                     - (int)&((struct socket*)0)->so_timeo),
  185.                         &sc ) ;
  186.                 return ( rc && (sc.so_state & SS_ISCONNECTING)
  187.                     ? "connct" 
  188.                     : rc && ((sc.so_options & SO_ACCEPTCONN)
  189.                       && !sc.so_qlen)
  190.                     ? "accept" : "socket" ) ;
  191.             case (int)&((struct socket*)0)->so_rcv.sb_cc :
  192.                 /* Read from an empty socket. Here we actually
  193.                    attempt to determine whether the socket
  194.                    structure in question really does refer to
  195.                    a socket, or whether it is in fact a pipe
  196.                    in disguise. */
  197.                 return ( getsocket( (struct socket*)(w
  198.                     - (int)&((struct socket*)0)->so_rcv.sb_cc),
  199.                         &sc )
  200.                     && sc.so_type == SOCK_STREAM
  201. #  ifdef BSD43
  202.                     && ((sc.so_state
  203.                         & (SS_ISCONNECTED|SS_CANTSENDMORE))
  204.                         == (SS_ISCONNECTED|SS_CANTSENDMORE))
  205. #  else
  206.                     && !sc.so_rcv.sb_hiwat
  207.                     && !sc.so_rcv.sb_mbmax
  208.                     && (sc.so_state
  209.                         & (SS_ISCONNECTED|SS_CANTRCVMORE))
  210. #  endif BSD43
  211.                     ? "rpipe" : "rsockt" ) ;
  212.             case (int)&((struct socket*)0)->so_snd.sb_cc :
  213.                 /* Write to a full socket. Again, we try
  214.                    to determine whether or not this is a
  215.                    real socket or a pipe. */
  216.                 return ( getsocket( (struct socket*)(w
  217.                     - (int)&((struct socket*)0)->so_snd.sb_cc),
  218.                         &sc )
  219. #  ifdef BSD43
  220.                     && sc.so_type == SOCK_STREAM
  221.                     && ((sc.so_state
  222.                         & (SS_ISCONNECTED|SS_CANTRCVMORE))
  223.                         == (SS_ISCONNECTED|SS_CANTRCVMORE))
  224. #  else
  225.                     && sc.so_rcv.sb_hiwat == 2048
  226.                     && sc.so_rcv.sb_mbmax == 4096
  227.                     && (sc.so_state
  228.                         & (SS_ISCONNECTED|SS_CANTSENDMORE))
  229. #  endif BSD43
  230.                     ? "wpipe" : "wsockt" ) ;
  231.             default :
  232.                 /* Other mbuf event */
  233.                 return ( "mbuf" ) ;
  234.         }
  235. # endif BSD42
  236.  
  237. # ifdef SUNOS41
  238.     if  ( w == (caddr_t)p->pr_p.p_uarea )
  239.         return ( "pause" ) ;
  240. # endif SUNOS41
  241.     /* Look in the symbol table for known wait addresses. */
  242.     for ( s = Symbollist ; s->s_kname ; s++ )
  243.         if ( s->s_wait && w == *s->s_info )
  244.             return ( s->s_wait ) ;
  245.  
  246. # ifdef SUNOS40
  247.     /* Have to check for ptys in a funny sort of way */
  248.     if ( INRANGE( w, Info.i_ptybase, &Info.i_ptybase[ Info.i_npty ] ) )
  249.     {
  250.         switch ( ((int)w - (int)Info.i_ptybase) % sizeof( struct pty ) )
  251.         {
  252.             case (int)&((struct pty*)0)->pt_flags :
  253.                 cp = "opty??" ;
  254.                 break ;
  255.             case (int)&((struct pty*)0)->pt_ttycommon.t_writeq :
  256.                 cp = "spty??" ;
  257.                 break ;
  258.             default :
  259.                 cp = "?pty??" ;
  260.         }
  261.         /* by the conventional naming, anyhow */
  262.         cp[4] = 'p' + (((int)w - (int)Info.i_ptybase)
  263.             / sizeof( struct pty )) / 16 ;
  264.         if ( ( cp[5] = '0' + (((int) w - (int)Info.i_ptybase)
  265.             / sizeof( struct pty )) % 16 ) > '9' )
  266.             cp[5] += 'a' - '9' - 1 ;
  267.         return( cp ) ;
  268.     }
  269.     /* Check for ttys last, since there may be a lot of them. */
  270.     if ( p->pr_tty != 0 )
  271.         if ( cp = gettty( p->pr_tty, w ) )
  272.             return( cp ) ;
  273.     for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
  274.         if ( cp = gettty( lp, w ) )
  275.             return( cp ) ;
  276. # else SUNOS40
  277.     /* Waiting for tty I/O ? If so, find which tty it is */
  278.     for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
  279.         if ( INRANGE( w, &lp->l_addr[0], &lp->l_addr[1] ) )
  280.         {
  281. #  ifdef DEC3100
  282.             /* Cretinous DEC compiler can't handle case
  283.                constructs like the following ... */
  284.             cp = "?tty??" ;
  285. #  else DEC3100
  286.             switch ( (int)w - (int)lp->l_addr )
  287.             {
  288.                 case (int)&((struct tty*)0)->t_rawq :
  289.                     /* Read from a tty or slave pty */
  290.                     cp = "rtty??" ;
  291.                     break ;
  292.                 case (int)&((struct tty*)0)->t_outq :
  293.                     /* Write to a tty or slave pty */
  294.                     cp = "wtty??" ;
  295.                     break ;
  296.                 case (int)&((struct tty*)0)->t_canq :
  297.                     /* Waiting for icon to be opened */
  298.                     cp = "itty??" ;
  299.                     break ;
  300.                 case (int)&((struct tty*)0)->t_state :
  301.                     /* Tty not open */
  302.                     cp = "otty??" ;
  303.                     break ;
  304.                 case (int)&((struct tty*)0)->t_outq.c_cf :
  305.                     /* Read from a controller pty */
  306.                     cp = "rpty??" ;
  307.                     break ;
  308.                 case (int)&((struct tty*)0)->t_rawq.c_cf :
  309.                     /* Write to a controller pty */
  310.                     cp = "wpty??" ;
  311.                     break ;
  312.                 default :
  313.                     cp = "?tty??" ;
  314.                     break ;
  315.             }
  316. #  endif DEC3100
  317.             cp[4] = lp->l_name[0] ;
  318.             cp[5] = lp->l_name[1] ;
  319.             return ( cp ) ;
  320.         }
  321. # endif SUNOS40
  322.  
  323.     /* No reason for the wait state has been found.
  324.        Return the wait channel as a hexadecimal address. */
  325. # ifdef SUN
  326.     (void)sprintf( wbuf, "x%05x", w - KERNELBASE ) ;
  327. # else
  328.     (void)sprintf( wbuf, "x%05x", w - 0x80000000 ) ;
  329. # endif
  330.     return ( wbuf ) ;
  331. }
  332.  
  333.  
  334. # ifdef BSD42
  335. /*
  336. ** GETSOCKET - Reads a `struct socket' from the kernel virtual memory address
  337. ** identified by `ks' into the buffer `s'.
  338. */
  339. getsocket ( ks, s )
  340.  
  341. struct socket                   *ks ;
  342. struct socket                   *s ;
  343.  
  344. {
  345.     return ( getkmem( (long)ks, (char*)s, sizeof( struct socket ) )
  346.         == sizeof( struct socket ) ) ;
  347. }
  348. # endif BSD42
  349.