home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume3 / sps / part1 / getcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  4.7 KB  |  180 lines

  1. # include       "sps.h"
  2. # include       "flags.h"
  3. # include       <h/vm.h>
  4. # ifdef BSD42
  5. # include    <machine/pte.h>
  6. # else
  7. # include       <h/pte.h>
  8. # endif
  9.  
  10. /*
  11. ** GETCMD - Returns a character string read from a process' upage.
  12. ** This character string should represent the arguments to the current process.
  13. */
  14. char    *getcmd ( p )
  15.  
  16. register struct process         *p ;
  17.  
  18. {
  19.     register int            *ip ;
  20.     register char           *cp ;
  21.     register char           *cp0 ;
  22.     unsigned                nbad ;
  23.     struct dblock           db ;
  24.     struct pte              ptetbl[ UPAGES + CLSIZE ] ;
  25.     union
  26.     {
  27.         char            a_argc[ CLSIZE * NBPG ] ;
  28.         int             a_argi[ CLSIZE * NBPG / sizeof( int ) ] ;
  29.     } argbuf ;
  30.     extern struct flags     Flg ;
  31.     extern union userstate  User ;
  32.     extern int              Flmem, Flswap ;
  33.     char                    *strcat(), *strncpy(), *strsave() ;
  34.  
  35.     p->pr_csaved = 0 ;
  36.     p->pr_upag = 0 ;
  37.     if ( p->pr_p.p_stat == SZOMB )
  38.         return ( "** Exit **" ) ;
  39.     if ( !(p->pr_p.p_flag & SLOAD) && Flg.flg_o )
  40.         return ( "** Swapped out **" ) ;
  41.     /* Find the process' upage */
  42.     if ( !getupage( p, ptetbl ) )           
  43.         return ( "** No upage **" ) ;
  44.     /* Is this a system process ? */
  45.     if ( p->pr_p.p_flag & SSYS )            
  46.         switch ( p->pr_p.p_pid )
  47.         {
  48.             case 0 :
  49.                 p->pr_upag = 1 ;
  50.                 return ( "Unix Swapper" ) ;
  51.             case 2 :
  52.                 p->pr_upag = 1 ;
  53.                 return ( "Unix Pager" ) ;
  54.             default :
  55.                 break ;
  56.         }
  57.     /* Look at the top of the upage to locate the command arguments.
  58.        The page is loaded if the process itself is loaded and the pte
  59.        contains is marked as valid. */
  60.     if ( (p->pr_p.p_flag & SLOAD)
  61.     && !ptetbl[0].pg_fod && ptetbl[0].pg_pfnum )
  62.     {       /* If the page is loaded, read the arguments from
  63.            physical memory. */
  64.         memseek( Flmem, (long)ctob( ptetbl[0].pg_pfnum ) ) ;
  65.         if ( read( Flmem, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
  66.             return ( "** Memory read error **" ) ;
  67.     }
  68.     else                            
  69.     {       /* Otherwise the page is on the swap device */
  70.         vstodb( 0, ctod( CLSIZE ), &User.u_us.u_smap, &db, 1 ) ;
  71. # ifdef BSD42
  72.         swseek( (long)dtob( db.db_base ) ) ;
  73. # else
  74.         swseek( (long)ctob( db.db_base ) ) ;
  75. # endif
  76.         if ( Flg.flg_o )
  77.             return ( "** Swapped page **" ) ;
  78.         if ( read( Flswap, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
  79.             return ( "** Swap device read error **" ) ;
  80.     }
  81.     /* Look down until the end of command arguments is found. */
  82.     p->pr_upag = 1 ;
  83.     p->pr_csaved = 1 ;
  84.     ip = &argbuf.a_argi[ CLSIZE*NBPG / sizeof( int ) ] ;
  85.     ip -= 2 ;
  86.     while ( *--ip )
  87.         if ( ip == &argbuf.a_argi[0] )
  88.             goto getsysargs ;
  89.     /* Process the command arguments, looking for nulls and unprintable
  90.        characters. */
  91.     cp0 = (char*)(ip + 1) ;
  92.     if ( !*cp0 )                    
  93.         cp0++ ;                 
  94.     if ( *cp0 )
  95.     {
  96.         nbad = 0 ;                      
  97.         for ( cp = cp0 ; cp < &argbuf.a_argc[ CLSIZE*NBPG ] ; cp++ )
  98.         {
  99.             *cp &= 0177 ;
  100.             if ( !*cp )             
  101.             {       /* Replace nulls with spaces */
  102.                 *cp = ' ' ;
  103.                 continue ;
  104.             }
  105.             if ( *cp < ' ' || *cp == 0177 )
  106.             {       /* Replace control characters with ?'s */
  107.                 if ( ++nbad > 5 )
  108.                 {
  109.                     *cp++ = ' ' ;
  110.                     break ;
  111.                 }
  112.                 *cp = '?' ;
  113.                 continue ;
  114.             }
  115.             if ( !Flg.flg_e && *cp == '=' )
  116.             {       /* Break on an `=' if we are not interested
  117.                    in the environment strings. */
  118.                 *cp = '\0' ;
  119.                 while ( cp > cp0 && *--cp != ' ' )
  120.                     *cp = '\0' ;
  121.                 break ;
  122.             }
  123.         }
  124.         while ( *--cp == ' ' )
  125.             *cp = '\0' ;
  126.         return ( strsave( cp0 ) ) ;
  127.     }
  128. getsysargs :
  129.     /* If the command arguments cannot be accessed from the user's memory
  130.        space, get the command name from the system's idea of what the
  131.        name should be. */
  132.     argbuf.a_argc[0] = '(' ;
  133.     (void)strncpy( &argbuf.a_argc[1], User.u_us.u_comm,
  134.         sizeof( User.u_us.u_comm ) ) ;
  135.     (void)strcat( &argbuf.a_argc[0], ")" ) ;
  136.     return ( strsave( argbuf.a_argc ) ) ;
  137. }
  138.  
  139. /*
  140. ** VSTODB - Given a base/size pair in virtual swap area,
  141. ** return a physical base/size pair which is the
  142. ** (largest) initial, physically contiguous block.
  143. /* This code is stolen from the kernel file /sys/sys/vm_drum.c.
  144. */
  145. vstodb ( vsbase, vssize, dmp, dbp, rev )
  146.  
  147. register int                    vsbase ;
  148. register int                    vssize;
  149. struct dmap                     *dmp ;
  150. register struct dblock          *dbp ;
  151. int                             rev ;
  152.  
  153. {
  154.     register int            blk ;
  155.     register swblk_t        *ip ;
  156. # ifdef BSD42
  157.     extern struct info      Info ;
  158. # endif
  159.  
  160. # ifdef BSD42
  161.     blk = Info.i_dmmin ;
  162. # else
  163.     blk = DMMIN ;
  164. # endif
  165.     ip = dmp->dm_map ;
  166.     while ( vsbase >= blk )
  167.     {
  168.         vsbase -= blk ;
  169. # ifdef BSD42
  170.         if ( blk < Info.i_dmmax )
  171. # else
  172.         if ( blk < DMMAX )
  173. # endif
  174.             blk *= 2 ;
  175.         ip++ ;
  176.     }
  177.     dbp->db_size = vssize < blk - vsbase ? vssize : blk - vsbase ;
  178.     dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
  179. }
  180.