home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume26 / sps3 / part02 / stream.c < prev    next >
C/C++ Source or Header  |  1992-05-08  |  5KB  |  227 lines

  1. # ifndef lint
  2. static char SccsId[] =  "@(#)stream.c    1.3\t8/22/91" ;
  3. # endif
  4.  
  5. # ifdef SUNOS40
  6. #  include        "sps.h"
  7. #  include        <h/stream.h>
  8. #  include        <h/vnode.h>
  9. #  ifdef SUNOS41
  10. #   include        <h/strstat.h>
  11. #  endif
  12.  
  13. static struct stdata    *pstreams ;
  14. static struct stdata    *pstreamsNSTREAMS ;
  15.  
  16. init_streams_tab()
  17. {
  18.     int            len ;
  19.     extern struct info    Info ;
  20.     register struct stdata    *s ;
  21.     struct vnode        *v ;
  22.     char            *getcore() ;
  23.  
  24.     if ( pstreams )
  25.     {
  26.         /* reinitializing */
  27.         for ( s = pstreams ; s <= pstreamsNSTREAMS ; s++ )
  28.             if ( s->sd_vnode != 0 )
  29.                 free( (char*)s->sd_vnode ) ;
  30.         free( (char*)pstreams ) ;
  31.     }
  32. #  ifdef SUNOS41
  33.     /*
  34.      * In SunOS 4.1, the stream heads are in a linked list.  A
  35.      * `struct strstat' contains the number of active streams; the
  36.      * variable `allstream' points to an apparently random
  37.      * position in a doubly linked `struct stdata' chain.
  38.      *
  39.      * To find all streams we'll have to scan the chain forwards
  40.      * AND backwards from `allstream'.  `int going_forwards' below
  41.      * tells which direction we are currently going.  Weird.
  42.      *
  43.      */
  44.  
  45.     {
  46.         struct strstat        strst ;
  47.         int            n ;
  48.         long            addr ;
  49.         struct stdata        *this_stream ;
  50.         int            going_forwards = 1 ;
  51.     
  52.         if ( getkmem ((long) Info.i_strst, (char *) &strst,
  53.             sizeof ( struct strstat )) != sizeof ( struct strstat ))
  54.             return 0 ;
  55.         len = strst.stream.use * sizeof( struct stdata ) ;
  56.         pstreams = (struct stdata *)getcore (len ) ;
  57.         addr = (long)Info.i_allstream ;
  58.         this_stream = pstreams ;
  59.         pstreamsNSTREAMS = pstreams - 1 ;
  60.         for (n = 0 ; n < strst.stream.use ; n++)
  61.         {
  62.             if ( getkmem ( addr, (char *) this_stream,
  63.                 sizeof ( struct stdata ))
  64.                 != sizeof ( struct stdata ))
  65.             {
  66.                 /*
  67.                  * If we are following the `sd_next' chain we'll
  68.                  * have to start over from the stream pointed to
  69.                  * by Info.i_allstream and scan `sd_prev'
  70.                  * backwards.
  71.                  */
  72.                 if ( going_forwards && n > 0 )
  73.                 {
  74.                     going_forwards = 0 ;
  75.                     addr = (long) pstreams[0].sd_prev ;
  76.                     n--;
  77.                     continue ;
  78.                 }
  79.                 if ( pstreamsNSTREAMS < pstreams )
  80.                     return 0 ;
  81.                 break ;
  82.             }
  83.             addr = going_forwards ? (long) this_stream->sd_next :
  84.                 (long) this_stream->sd_prev ;
  85.             this_stream++ ;
  86.             pstreamsNSTREAMS++ ;
  87.         }
  88.     }
  89. #  else SUNOS41
  90.     len = ((Info.i_streamsNSTREAMS - Info.i_streams) + 1)
  91.         * sizeof( struct stdata ) ;
  92.     pstreams = (struct stdata *)getcore( len ) ;
  93.     pstreamsNSTREAMS = pstreams + (len / sizeof( struct stdata ) ) ;
  94.     if ( getkmem( (long)Info.i_streams, (char *)pstreams, len ) != len )
  95.         return( 0 ) ;
  96. #  endif SUNOS41
  97.  
  98.     for ( s = pstreams ; s <= pstreamsNSTREAMS ; s++ )
  99.         if ( s->sd_vnode != 0 )
  100.         {
  101.             if ( ( v = (struct vnode*)getcore( sizeof( *v ) ) )
  102.             && getkmem( (long)s->sd_vnode, (char*)v, sizeof( *v ) )
  103.             == sizeof( *v ) )
  104.             {
  105.                 s->sd_vnode = v ;
  106.                 continue ;
  107.             }
  108.  
  109.             s->sd_vnode = 0 ;
  110.         }
  111.     return( 1 ) ;
  112. }
  113.  
  114.  
  115. #  ifdef SUNOS41
  116. struct sess *find_session ( addr )
  117.  
  118. struct sess            *addr ;
  119.  
  120. {
  121.     /*
  122.      * SunOS 4.1 seems to store controlling tty's in a "struct
  123.      * sess" which is accessible as p->p_sessp.  Another layer
  124.      * of indirection to wade through...
  125.      *
  126.      * To make this a tiny bit faster, I'll store sessions in a
  127.      * linked list as I read them in with getkmem; subsequent
  128.      * calls to find_session() check the cache.
  129.      */
  130.  
  131.     struct sps_sess {
  132.         struct sess        sess ;
  133.         struct sess        *addr ;
  134.         struct sps_sess        *next ;
  135.     };
  136.  
  137.     static struct sps_sess        *sessions ; /* Cache of known sessions*/
  138.     register struct sps_sess    *s ;
  139.  
  140.     /* Try to find the session in the cache */
  141.     for ( s = sessions ; s ; s = s->next )
  142.         if ( s->addr == addr )
  143.             return &s->sess ;
  144.     /* Not found; get it from kmem and put it in the cache */
  145.     s = (struct sps_sess *)getcore( sizeof ( struct sps_sess ) ) ;
  146.     if ( getkmem ((long) addr, (char *) &s->sess,
  147.             sizeof ( struct sess )) != sizeof ( struct sess ) )
  148.         return 0 ;
  149.     s->addr = addr ;
  150.     s->next = sessions ;
  151.     sessions = s ;
  152.     return &s->sess ;
  153. }
  154. #  endif SUNOS41
  155.  
  156. struct stdata *getstdata ( st, dev )
  157.  
  158. struct streamtab                *st ;
  159. dev_t                            dev ;
  160.  
  161. {
  162.     register struct stdata  *s ;
  163.  
  164.     for ( s = pstreams ; s <= pstreamsNSTREAMS ; s++ )
  165.         if ( s->sd_strtab == st && s->sd_vnode
  166.         && s->sd_vnode->v_rdev == dev )
  167.             return( s ) ;
  168.     return( 0 ) ;
  169. }
  170.  
  171. /* 1 if `w' is in the address range defined by `a1' and `a2' ... */
  172. # define        INRANGE( w, a1, a2 ) \
  173.             ( (caddr_t)(a1) <= (w) && (w) < (caddr_t)(a2) )
  174.  
  175. char *gettty ( lp, w )
  176.  
  177. register struct ttyline         *lp ;
  178. caddr_t                         w ;
  179.  
  180. {
  181.     struct stdata           *s ;
  182.     struct queue            *q ;
  183.     struct queue            qq[2] ;
  184.     char                    *cp = 0 ;
  185.  
  186.     if ( ( s = lp->l_stdata ) == 0 )
  187.         return( 0 ) ;
  188.  
  189.     q = s->sd_wrq ;        /* get write queue (only queue_t in stdata) */
  190.     do
  191.     {
  192.         if ( INRANGE( w, RD( q ), q ) )
  193.         {            /* check read queue */
  194.             cp = "rtty??" ;
  195.             break ;
  196.         }
  197.         if ( INRANGE( w, q, WR ( q ) ) )
  198.         {            /* check write queue */
  199.             cp = "wtty??" ;
  200.             break ;
  201.         }
  202.         /* check queue private data structures - useful??? */
  203.         if ( getkmem( (long)RD( q ), (char*)qq, sizeof( qq ) )
  204.         != sizeof( qq ) )
  205.             break ;
  206.         if ( INRANGE( w, qq[0].q_ptr, qq[0].q_ptr + 1 ) )
  207.         {
  208.             cp = "r?ty??" ;
  209.         }
  210.         if ( INRANGE( w, qq[1].q_ptr, qq[1].q_ptr + 1 ) )
  211.         {
  212.             cp = "w?ty??" ;
  213.         }
  214.         q = qq[1].q_next ;
  215.     }
  216.     while ( q ) ;
  217.     if ( cp )
  218.     {
  219.         cp[4] = lp->l_name[0] ;
  220.         cp[5] = lp->l_name[1] ;
  221.         return( cp ) ;
  222.     }
  223.     return( 0 ) ;            /* chain down list? */
  224. }
  225. # endif SUNOS40
  226.  
  227.