home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / sps / part02 / getcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-07-21  |  4.9 KB  |  184 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.     /* Fix by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
  58.     /* Check for lack of stack, jack! (Sun 3.0 biod's) */
  59.     if (User.u_us.u_ssize == 0)
  60.         goto getsysargs ;
  61.     /* Look at the top of the upage to locate the command arguments.
  62.        The page is loaded if the process itself is loaded and the pte
  63.        contains is marked as valid. */
  64.     if ( (p->pr_p.p_flag & SLOAD)
  65.     && !ptetbl[0].pg_fod && ptetbl[0].pg_pfnum )
  66.     {       /* If the page is loaded, read the arguments from
  67.            physical memory. */
  68.         memseek( Flmem, (long)ctob( ptetbl[0].pg_pfnum ) ) ;
  69.         if ( read( Flmem, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
  70.             return ( "** Memory read error **" ) ;
  71.     }
  72.     else                            
  73.     {       /* Otherwise the page is on the swap device */
  74.         vstodb( 0, ctod( CLSIZE ), &User.u_us.u_smap, &db, 1 ) ;
  75. # ifdef BSD42
  76.         swseek( (long)dtob( db.db_base ) ) ;
  77. # else
  78.         swseek( (long)ctob( db.db_base ) ) ;
  79. # endif
  80.         if ( Flg.flg_o )
  81.             return ( "** Swapped page **" ) ;
  82.         if ( read( Flswap, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
  83.             return ( "** Swap device read error **" ) ;
  84.     }
  85.     /* Look down until the end of command arguments is found. */
  86.     p->pr_upag = 1 ;
  87.     p->pr_csaved = 1 ;
  88.     ip = &argbuf.a_argi[ CLSIZE*NBPG / sizeof( int ) ] ;
  89.     ip -= 2 ;
  90.     while ( *--ip )
  91.         if ( ip == &argbuf.a_argi[0] )
  92.             goto getsysargs ;
  93.     /* Process the command arguments, looking for nulls and unprintable
  94.        characters. */
  95.     cp0 = (char*)(ip + 1) ;
  96.     if ( !*cp0 )                    
  97.         cp0++ ;                 
  98.     if ( *cp0 )
  99.     {
  100.         nbad = 0 ;                      
  101.         for ( cp = cp0 ; cp < &argbuf.a_argc[ CLSIZE*NBPG ] ; cp++ )
  102.         {
  103.             *cp &= 0177 ;
  104.             if ( !*cp )             
  105.             {       /* Replace nulls with spaces */
  106.                 *cp = ' ' ;
  107.                 continue ;
  108.             }
  109.             if ( *cp < ' ' || *cp == 0177 )
  110.             {       /* Replace control characters with ?'s */
  111.                 if ( ++nbad > 5 )
  112.                 {
  113.                     *cp++ = ' ' ;
  114.                     break ;
  115.                 }
  116.                 *cp = '?' ;
  117.                 continue ;
  118.             }
  119.             if ( !Flg.flg_e && *cp == '=' )
  120.             {       /* Break on an `=' if we are not interested
  121.                    in the environment strings. */
  122.                 *cp = '\0' ;
  123.                 while ( cp > cp0 && *--cp != ' ' )
  124.                     *cp = '\0' ;
  125.                 break ;
  126.             }
  127.         }
  128.         while ( *--cp == ' ' )
  129.             *cp = '\0' ;
  130.         return ( strsave( cp0 ) ) ;
  131.     }
  132. getsysargs :
  133.     /* If the command arguments cannot be accessed from the user's memory
  134.        space, get the command name from the system's idea of what the
  135.        name should be. */
  136.     argbuf.a_argc[0] = '(' ;
  137.     (void)strncpy( &argbuf.a_argc[1], User.u_us.u_comm,
  138.         sizeof( User.u_us.u_comm ) ) ;
  139.     (void)strcat( &argbuf.a_argc[0], ")" ) ;
  140.     return ( strsave( argbuf.a_argc ) ) ;
  141. }
  142.  
  143. /*
  144. ** VSTODB - Given a base/size pair in virtual swap area,
  145. ** return a physical base/size pair which is the
  146. ** (largest) initial, physically contiguous block.
  147. /* This code is stolen from the kernel file /sys/sys/vm_drum.c.
  148. */
  149. vstodb ( vsbase, vssize, dmp, dbp, rev )
  150.  
  151. register int                    vsbase ;
  152. register int                    vssize;
  153. struct dmap                     *dmp ;
  154. register struct dblock          *dbp ;
  155. int                             rev ;
  156.  
  157. {
  158.     register int            blk ;
  159.     register swblk_t        *ip ;
  160. # ifdef BSD42
  161.     extern struct info      Info ;
  162. # endif
  163.  
  164. # ifdef BSD42
  165.     blk = Info.i_dmmin ;
  166. # else
  167.     blk = DMMIN ;
  168. # endif
  169.     ip = dmp->dm_map ;
  170.     while ( vsbase >= blk )
  171.     {
  172.         vsbase -= blk ;
  173. # ifdef BSD42
  174.         if ( blk < Info.i_dmmax )
  175. # else
  176.         if ( blk < DMMAX )
  177. # endif
  178.             blk *= 2 ;
  179.         ip++ ;
  180.     }
  181.     dbp->db_size = vssize < blk - vsbase ? vssize : blk - vsbase ;
  182.     dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
  183. }
  184.