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