home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / sps3 / part03 / waitingfor.c < prev   
Encoding:
C/C++ Source or Header  |  1992-05-08  |  9.8 KB  |  353 lines

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