home *** CD-ROM | disk | FTP | other *** search
- # ifndef lint
- static char SccsId[] = "@(#)waitingfor.c 1.5\t8/6/90" ;
- # endif
-
- # include "sps.h"
- # ifndef SUNOS40
- # include <h/text.h>
- # endif SUNOS40
-
- # ifdef NFS
- # ifdef DEC3100
- # include <h/gnode.h>
- # include <h/inode.h>
- # else DEC3100
- # include <h/vnode.h>
- # include <ufs/inode.h>
- # endif DEC3100
- # else
- # include <h/inode.h>
- # endif NFS
-
- # include <h/ioctl.h>
- # ifdef SUNOS40
- # include <h/stream.h>
- # include <h/tty.h>
- # include <h/ptyvar.h>
- # else SUNOS40
- # include <h/tty.h>
- # endif SUNOS40
-
- # include <h/buf.h>
- # ifdef BSD42
- # ifdef NFS
- # ifndef NOQUOTA
- # ifdef DEC3100
- # include <h/quota.h>
- # else
- # include <ufs/quota.h>
- # endif DEC3100
- # endif NOQUOTA
- # else NFS
- # include <h/quota.h>
- # endif NFS
- # include <h/mbuf.h>
- # include <h/socket.h>
- # include <h/socketvar.h>
- # endif BSD42
-
- /* 1 if `w' is in the address range defined by `a1' and `a2' ... */
- # define INRANGE( w, a1, a2 ) \
- ( (caddr_t)(a1) <= (w) && (w) < (caddr_t)(a2) )
-
- /* NFS changes incorporated by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
-
- /* WAITINGFOR - Determine what a process is waiting for and describe it. */
- char *waitingfor ( p )
-
- struct process *p ;
-
- {
- register caddr_t w ;
- register struct ttyline *lp ;
- register struct symbol *s ;
- register char *cp ;
- # ifdef BSD42
- struct socket sc ;
- # endif
- int rc ;
- static char wbuf[ 8 ] ;
- extern struct info Info ;
- extern struct symbol Symbollist[] ;
- char *sprintf() ;
- # ifdef SUNOS40
- char *gettty() ;
- # endif
-
- w = p->pr_p.p_wchan ;
- if ( !w )
- return ( "null" ) ;
- /* Waiting for a child process, alternatively in a vfork() ? */
- if ( INRANGE( w, Info.i_proc0, &Info.i_proc0[ Info.i_nproc ] ) )
- return ( p->pr_p.p_flag & SNOVM ? "vfork" : "child" ) ;
- # ifndef SUNOS40
- /* Waiting for a page to be brought in ? */
- if ( INRANGE( w, Info.i_swbuf0, &Info.i_swbuf0[ Info.i_nswbuf ] ) )
- return ( "swap" ) ;
- /* Waiting for discio through a block device to complete ? */
- if ( INRANGE( w, Info.i_buf0, &Info.i_buf0[ Info.i_nbuf ] ) )
- /* SHOULD ACTUALLY READ AS "blkio" BUT "discio" IS WHAT
- IS GENERALLY MEANT HERE. */
- return ( "discio" ) ;
- /* Waiting for a text page to be brought in ? */
- if ( INRANGE( w, Info.i_text0, &Info.i_text0[ Info.i_ntext ] ) )
- return ( "swtext" ) ;
- # endif SUNOS40
-
- # ifdef BSD42
- # ifndef NOQUOTA
- /* Waiting for an event associated with the quota system ? */
- if ( INRANGE( w, Info.i_quota0, &Info.i_quota0[ Info.i_nquota ] ) )
- return ( "quota" ) ;
- # endif NOQUOTA
- # endif BSD42
-
- # ifndef SUNOS41
- /* Sorry, I don't know how to do this...
- * I kinda think that SunOS 4.1 allocates inode
- * buffer entries dynamically. Maybe it could be
- * possible to read in all "struct file"s and
- * compare each file.f_data to the wait channel. ++sja
- */
- /* Waiting for an inode ? */
- if ( INRANGE( w, Info.i_inode0, &Info.i_inode0[ Info.i_ninode ] ) )
- # ifdef ULTRIX20
- switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct gnode ))
- # else
- switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct inode ))
- # endif ULTRIX20
- {
- # ifdef BSD42
- # ifdef NFS
- case (int)&((struct inode*)0)->i_vnode.v_exlockc :
- /* Exclusive lock on this inode */
- return ( "exlock" ) ;
- case (int)&((struct inode*)0)->i_vnode.v_shlockc :
- /* Shared lock on this inode */
- return ( "shlock" ) ;
- # else NFS
- # ifdef ULTRIX20
- # ifndef DEC3100
- /* Compile this code with gcc if you want to run it
- properly. The DEC compiler can't handle this. */
- case (int)&((struct gnode*)0)->g_exlockc :
- /* Exclusive lock on this inode */
- return ( "exlock" ) ;
- case (int)&((struct gnode*)0)->g_shlockc :
- /* Shared lock on this inode */
- return ( "shlock" ) ;
- case (int)&((struct gnode*)0)->g_frcnt :
- /* Open fifo with no readers */
- return ( "wfifo" ) ;
- case (int)&((struct gnode*)0)->g_fwcnt :
- /* Open fifo with no writers */
- return ( "rfifo" ) ;
- # endif DEC3100
- # else ULTRIX20
- case (int)&((struct inode*)0)->i_exlockc :
- /* Exclusive lock on this inode */
- return ( "exlock" ) ;
- case (int)&((struct inode*)0)->i_shlockc :
- /* Shared lock on this inode */
- return ( "shlock" ) ;
- # endif ULTRIX20
- # endif NFS
- # else BSD42
- case 1 :
- return ( "wpipe" ) ;
- case 2 :
- return ( "rpipe" ) ;
- case (int)&((struct inode*)0)->i_un.i_group.g_datq :
- return ( "rmux" ) ;
- # endif BSD42
- default :
- /* Inode probably locked */
- return ( "inode" ) ;
- }
- # endif SUNOS41
-
- # if defined(BSD42) && (defined(SUNOS40) || defined(NMBCLUSTERS))
- /* Waiting for a structure inside an mbuf ? If so, try to find why */
- # ifdef SUNOS40
- if ( INRANGE( w, Info.i_mbutl,
- &Info.i_mbutl[ MBPOOLBYTES / sizeof( struct mbuf ) ] ) )
- # else
- if ( INRANGE( w, Info.i_mbutl,
- &Info.i_mbutl[ NMBCLUSTERS * CLBYTES / sizeof( struct mbuf ) ] ) )
- # endif SUNOS40
- switch ( ((int)w - (int)Info.i_mbutl) % sizeof( struct mbuf )
- - (int)&((struct mbuf*)0)->m_dat[0] )
- {
- case (int)&((struct socket*)0)->so_timeo :
- /* Socket timeout event - Guess why */
- rc = getsocket( (struct socket*)(w
- - (int)&((struct socket*)0)->so_timeo),
- &sc ) ;
- return ( rc && (sc.so_state & SS_ISCONNECTING)
- ? "connct"
- : rc && ((sc.so_options & SO_ACCEPTCONN)
- && !sc.so_qlen)
- ? "accept" : "socket" ) ;
- case (int)&((struct socket*)0)->so_rcv.sb_cc :
- /* Read from an empty socket. Here we actually
- attempt to determine whether the socket
- structure in question really does refer to
- a socket, or whether it is in fact a pipe
- in disguise. */
- return ( getsocket( (struct socket*)(w
- - (int)&((struct socket*)0)->so_rcv.sb_cc),
- &sc )
- && sc.so_type == SOCK_STREAM
- # ifdef BSD43
- && ((sc.so_state
- & (SS_ISCONNECTED|SS_CANTSENDMORE))
- == (SS_ISCONNECTED|SS_CANTSENDMORE))
- # else
- && !sc.so_rcv.sb_hiwat
- && !sc.so_rcv.sb_mbmax
- && (sc.so_state
- & (SS_ISCONNECTED|SS_CANTRCVMORE))
- # endif BSD43
- ? "rpipe" : "rsockt" ) ;
- case (int)&((struct socket*)0)->so_snd.sb_cc :
- /* Write to a full socket. Again, we try
- to determine whether or not this is a
- real socket or a pipe. */
- return ( getsocket( (struct socket*)(w
- - (int)&((struct socket*)0)->so_snd.sb_cc),
- &sc )
- # ifdef BSD43
- && sc.so_type == SOCK_STREAM
- && ((sc.so_state
- & (SS_ISCONNECTED|SS_CANTRCVMORE))
- == (SS_ISCONNECTED|SS_CANTRCVMORE))
- # else
- && sc.so_rcv.sb_hiwat == 2048
- && sc.so_rcv.sb_mbmax == 4096
- && (sc.so_state
- & (SS_ISCONNECTED|SS_CANTSENDMORE))
- # endif BSD43
- ? "wpipe" : "wsockt" ) ;
- default :
- /* Other mbuf event */
- return ( "mbuf" ) ;
- }
- # endif BSD42
-
- # ifdef SUNOS41
- if ( w == (caddr_t)p->pr_p.p_uarea )
- return ( "pause" ) ;
- # endif SUNOS41
- /* Look in the symbol table for known wait addresses. */
- for ( s = Symbollist ; s->s_kname ; s++ )
- if ( s->s_wait && w == *s->s_info )
- return ( s->s_wait ) ;
-
- # ifdef SUNOS40
- /* Have to check for ptys in a funny sort of way */
- if ( INRANGE( w, Info.i_ptybase, &Info.i_ptybase[ Info.i_npty ] ) )
- {
- switch ( ((int)w - (int)Info.i_ptybase) % sizeof( struct pty ) )
- {
- case (int)&((struct pty*)0)->pt_flags :
- cp = "opty??" ;
- break ;
- case (int)&((struct pty*)0)->pt_ttycommon.t_writeq :
- cp = "spty??" ;
- break ;
- default :
- cp = "?pty??" ;
- }
- /* by the conventional naming, anyhow */
- cp[4] = 'p' + (((int)w - (int)Info.i_ptybase)
- / sizeof( struct pty )) / 16 ;
- if ( ( cp[5] = '0' + (((int) w - (int)Info.i_ptybase)
- / sizeof( struct pty )) % 16 ) > '9' )
- cp[5] += 'a' - '9' - 1 ;
- return( cp ) ;
- }
- /* Check for ttys last, since there may be a lot of them. */
- if ( p->pr_tty != 0 )
- if ( cp = gettty( p->pr_tty, w ) )
- return( cp ) ;
- for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
- if ( cp = gettty( lp, w ) )
- return( cp ) ;
- # else SUNOS40
- /* Waiting for tty I/O ? If so, find which tty it is */
- for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
- if ( INRANGE( w, &lp->l_addr[0], &lp->l_addr[1] ) )
- {
- # ifdef DEC3100
- /* Cretinous DEC compiler can't handle case
- constructs like the following ... */
- cp = "?tty??" ;
- # else DEC3100
- switch ( (int)w - (int)lp->l_addr )
- {
- case (int)&((struct tty*)0)->t_rawq :
- /* Read from a tty or slave pty */
- cp = "rtty??" ;
- break ;
- case (int)&((struct tty*)0)->t_outq :
- /* Write to a tty or slave pty */
- cp = "wtty??" ;
- break ;
- case (int)&((struct tty*)0)->t_canq :
- /* Waiting for icon to be opened */
- cp = "itty??" ;
- break ;
- case (int)&((struct tty*)0)->t_state :
- /* Tty not open */
- cp = "otty??" ;
- break ;
- case (int)&((struct tty*)0)->t_outq.c_cf :
- /* Read from a controller pty */
- cp = "rpty??" ;
- break ;
- case (int)&((struct tty*)0)->t_rawq.c_cf :
- /* Write to a controller pty */
- cp = "wpty??" ;
- break ;
- default :
- cp = "?tty??" ;
- break ;
- }
- # endif DEC3100
- cp[4] = lp->l_name[0] ;
- cp[5] = lp->l_name[1] ;
- return ( cp ) ;
- }
- # endif SUNOS40
-
- /* No reason for the wait state has been found.
- Return the wait channel as a hexadecimal address. */
- # ifdef SUN
- (void)sprintf( wbuf, "x%05x", w - KERNELBASE ) ;
- # else
- (void)sprintf( wbuf, "x%05x", w - 0x80000000 ) ;
- # endif
- return ( wbuf ) ;
- }
-
-
- # ifdef BSD42
- /*
- ** GETSOCKET - Reads a `struct socket' from the kernel virtual memory address
- ** identified by `ks' into the buffer `s'.
- */
- getsocket ( ks, s )
-
- struct socket *ks ;
- struct socket *s ;
-
- {
- return ( getkmem( (long)ks, (char*)s, sizeof( struct socket ) )
- == sizeof( struct socket ) ) ;
- }
- # endif BSD42
-