home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume23 / sps2 / part02 / stream.c < prev   
C/C++ Source or Header  |  1991-01-08  |  5KB  |  225 lines

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