home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume3 / sps / part2 / waitingfor.c < prev   
Encoding:
C/C++ Source or Header  |  1986-11-30  |  5.7 KB  |  196 lines

  1. # include       "sps.h"
  2. # include       <h/tty.h>
  3. # include       <h/text.h>
  4. # ifdef SUN
  5. # include       <h/vnode.h>
  6. # include       <ufs/inode.h>
  7. # else
  8. # include       <h/inode.h>
  9. # endif
  10. # include       <h/buf.h>
  11. # ifdef BSD42
  12. # include       <h/quota.h>
  13. # include       <h/mbuf.h>
  14. # include       <h/socket.h>
  15. # include       <h/socketvar.h>
  16. # endif
  17.  
  18. /* 1 if `w' is in the address range defined by `a1' and `a2' ... */
  19. # define        INRANGE( w, a1, a2 ) \
  20.             ( (caddr_t)(a1) <= (w) && (w) < (caddr_t)(a2) )
  21.  
  22. /* WAITINGFOR - Determine what a process is waiting for and describe it. */
  23. char    *waitingfor ( p )
  24.  
  25. struct process                  *p ;
  26.  
  27. {
  28.     register caddr_t        w ;
  29.     register struct ttyline *lp ;
  30.     register struct symbol  *s ;
  31.     register char           *cp ;
  32. # ifdef BSD42
  33.     struct socket           sc ;
  34. # endif
  35.     static char             wbuf[ 8 ] ;
  36.     extern struct info      Info ;
  37.     extern struct symbol    Symbollist[] ;
  38.     char                    *sprintf() ;
  39.  
  40.     w = p->pr_p.p_wchan ;
  41.     if ( !w )
  42.         return ( "null" ) ;
  43.     /* Waiting for a child process, alternatively in a vfork() ? */
  44.     if ( INRANGE( w, Info.i_proc0, &Info.i_proc0[ Info.i_nproc ] ) )
  45.         return ( p->pr_p.p_flag & SNOVM ? "vfork" : "child" ) ;
  46.     /* Waiting for a page to be brought in ? */
  47.     if ( INRANGE( w, Info.i_swbuf0, &Info.i_swbuf0[ Info.i_nswbuf ] ) )
  48.         return ( "swap" ) ;
  49.     /* Waiting for discio through a block device to complete ? */
  50.     if ( INRANGE( w, Info.i_buf0, &Info.i_buf0[ Info.i_nbuf ] ) )
  51.         /* SHOULD ACTUALLY READ AS "blkio" BUT "discio" IS WHAT
  52.            IS GENERALLY MEANT HERE. */
  53.         return ( "discio" ) ;
  54.     /* Waiting for a text page to be brought in ? */
  55.     if ( INRANGE( w, Info.i_text0, &Info.i_text0[ Info.i_ntext ] ) )
  56.         return ( "swtext" ) ;
  57. # ifdef BSD42
  58.     /* Waiting for an event associated with the quota system ? */
  59.     if ( INRANGE( w, Info.i_quota0, &Info.i_quota0[ Info.i_nquota ] ) )
  60.         return ( "quota" ) ;
  61. # endif
  62.     /* Waiting for tty I/O ? If so, find which tty it is */
  63.     for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
  64.         if ( INRANGE( w, &lp->l_addr[0], &lp->l_addr[1] ) )
  65.         {
  66.             switch ( w - (int)lp->l_addr )
  67.             {
  68.                 case (int)&((struct tty*)0)->t_rawq :
  69.                     /* Read from a tty or slave pty */
  70.                     cp = "rtty??" ;
  71.                     break ;
  72.                 case (int)&((struct tty*)0)->t_outq :
  73.                     /* Write to a tty or slave pty */
  74.                     cp = "wtty??" ;
  75.                     break ;
  76.                 case (int)&((struct tty*)0)->t_state :
  77.                     /* Tty not open */
  78.                     cp = "otty??" ;
  79.                     break ;
  80.                 case (int)&((struct tty*)0)->t_outq.c_cf :
  81.                     /* Read from a controller pty */
  82.                     cp = "rpty??" ;
  83.                     break ;
  84.                 case (int)&((struct tty*)0)->t_rawq.c_cf :
  85.                     /* Write to a controller pty */
  86.                     cp = "wpty??" ;
  87.                     break ;
  88.                 default :
  89.                     cp = "?tty??" ;
  90.                     break ;
  91.             }
  92.             cp[4] = lp->l_name[0] ;
  93.             cp[5] = lp->l_name[1] ;
  94.             return ( cp ) ;
  95.         }
  96.     /* Waiting for an inode ? */
  97.     if ( INRANGE( w, Info.i_inode0, &Info.i_inode0[ Info.i_ninode ] ) )
  98.         switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct inode ))
  99.         {
  100. # ifdef BSD42
  101. # ifndef SUN
  102.             case (int)&((struct inode*)0)->i_exlockc :
  103.                 /* Exclusive lock on this inode */
  104.                 return ( "exlock" ) ;
  105.             case (int)&((struct inode*)0)->i_shlockc :
  106.                 /* Shared lock on this inode */
  107.                 return ( "shlock" ) ;
  108. # endif
  109. # else
  110.             case 1 :
  111.                 return ( "wpipe" ) ;
  112.             case 2 :
  113.                 return ( "rpipe" ) ;
  114.             case (int)&((struct inode*)0)->i_un.i_group.g_datq :
  115.                 return ( "rmux" ) ;
  116. # endif
  117.             default :
  118.                 /* Inode probably locked */
  119.                 return ( "inode" ) ;
  120.         }
  121. # ifdef BSD42
  122.     /* Waiting for a structure inside an mbuf ? If so, try to find why */
  123.     if ( INRANGE( w, Info.i_mbutl,
  124.     &Info.i_mbutl[ NMBCLUSTERS * CLBYTES / sizeof( struct mbuf ) ] ) )
  125.         switch ( ((int)w - (int)Info.i_mbutl) % sizeof( struct mbuf )
  126.             - (int)&((struct mbuf*)0)->m_dat[0] )
  127.         {
  128.             case (int)&((struct socket*)0)->so_timeo :
  129.                 /* Socket timeout event */
  130.                 return ( "socket" ) ;
  131.             case (int)&((struct socket*)0)->so_rcv.sb_cc :
  132.                 /* Read from an empty socket. Here we actually
  133.                    attempt to determine whether the socket
  134.                    structure in question really does refer to
  135.                    a socket, or whether it is in fact a pipe
  136.                    in disguise. */
  137.                 return ( getsocket( (struct socket*)(w
  138.                     - (int)&((struct socket*)0)->so_rcv.sb_cc),
  139.                         &sc )
  140.                     && sc.so_type == SOCK_STREAM
  141.                     && !sc.so_rcv.sb_hiwat
  142.                     && !sc.so_rcv.sb_mbmax
  143.                     && (sc.so_state
  144.                         & (SS_ISCONNECTED|SS_CANTRCVMORE))
  145.                     ? "rpipe" : "rsockt" ) ;
  146.             case (int)&((struct socket*)0)->so_snd.sb_cc :
  147.                 /* Write to a full socket. Again, we try
  148.                    to determine whether or not this is a
  149.                    real socket or a pipe. */
  150.                 return ( getsocket( (struct socket*)(w
  151.                     - (int)&((struct socket*)0)->so_snd.sb_cc),
  152.                         &sc )
  153.                     && sc.so_type == SOCK_STREAM
  154.                     && sc.so_rcv.sb_hiwat == 2048
  155.                     && sc.so_rcv.sb_mbmax == 4096
  156.                     && (sc.so_state
  157.                         & (SS_ISCONNECTED|SS_CANTSENDMORE))
  158.                     ? "wpipe" : "wsockt" ) ;
  159.             default :
  160.                 /* Other mbuf event */
  161.                 return ( "mbuf" ) ;
  162.         }
  163. # endif
  164.     /* Look in the symbol table for known wait addresses. */
  165.     for ( s = Symbollist ; s->s_kname ; s++ )
  166.         if ( s->s_wait && w == *s->s_info )
  167.             return ( s->s_wait ) ;  
  168.     /* No reason for the wait state has been found.
  169.        Return the wait channel as a hexadecimal address. */
  170. # ifdef SUN
  171.     (void)sprintf( wbuf, "x%05x", w ) ;
  172. # else
  173.     (void)sprintf( wbuf, "x%05x", w - 0x80000000 ) ;
  174. # endif
  175.     return ( wbuf ) ;
  176. }
  177.  
  178. # ifdef BSD42
  179. /*
  180. ** GETSOCKET - Reads a `struct socket' from the kernel virtual memory address
  181. ** identified by `ks' into the buffer `s'.
  182. */
  183. getsocket ( ks, s )
  184.  
  185. struct socket                   *ks ;
  186. struct socket                   *s ;
  187.  
  188. {
  189.     extern int              Flkmem ;
  190.  
  191.     memseek( Flkmem, (long)ks ) ;
  192.     return ( read( Flkmem, (char*)s, sizeof( struct socket ) )
  193.         == sizeof( struct socket ) ) ;
  194. }
  195. # endif
  196.