DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T w

⟦528b140b4⟧ TextFile

    Length: 6500 (0x1964)
    Types: TextFile
    Names: »waitingfor.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec8/sps/waitingfor.c« 

TextFile

# include       "sps.h"
# include       <h/text.h>
# ifdef SUN
# include       <h/vnode.h>
# include       <ufs/inode.h>
# else
# include       <h/inode.h>
# endif SUN
# include       <h/ioctl.h>
# include       <h/tty.h>
# include       <h/buf.h>
# ifdef BSD42
# ifndef SUN
# include       <h/quota.h>
# endif SUN
# 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) )

/* 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() ;

	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" ) ;
	/* 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" ) ;
# ifdef BSD42
# ifndef SUN
	/* Waiting for an event associated with the quota system ? */
	if ( INRANGE( w, Info.i_quota0, &Info.i_quota0[ Info.i_nquota ] ) )
		return ( "quota" ) ;
# endif SUN
# endif BSD42
	/* 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] ) )
		{
			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_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 ;
			}
			cp[4] = lp->l_name[0] ;
			cp[5] = lp->l_name[1] ;
			return ( cp ) ;
		}
	/* Waiting for an inode ? */
	if ( INRANGE( w, Info.i_inode0, &Info.i_inode0[ Info.i_ninode ] ) )
		switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct inode ))
		{
# ifdef BSD42
# ifndef SUN
			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 SUN
# else
			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" ) ;
		}
# ifdef BSD42
	/* Waiting for a structure inside an mbuf ? If so, try to find why */
	if ( INRANGE( w, Info.i_mbutl,
	&Info.i_mbutl[ NMBCLUSTERS * CLBYTES / sizeof( struct mbuf ) ] ) )
		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 SUN
	/* 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 ) ;  
	/* 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 ) ;
# else
	(void)sprintf( wbuf, "x%05x", w - 0x80000000 ) ;
# endif SUN
	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 ;

{
	extern int              Flkmem ;

	memseek( Flkmem, (long)ks ) ;
	return ( read( Flkmem, (char*)s, sizeof( struct socket ) )
		== sizeof( struct socket ) ) ;
}
# endif BSD42