home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2120 < prev    next >
Internet Message Format  |  1990-12-28  |  69KB

  1. From: robert@olsen.UUCP (Robert Ward)
  2. Newsgroups: alt.sources
  3. Subject: SPS for SunOS4.1 and DEC 3100's - Shar 3 of 3
  4. Message-ID: <201@frey.UUCP>
  5. Date: 19 Nov 90 15:44:49 GMT
  6.  
  7.  
  8. #!/bin/sh
  9. #
  10. # This is a shar (shell archive) file.
  11. # In order to extract the contents of this archive, remove everything
  12. # above the "#!/bin/sh" line.  Then execute the remaining file with
  13. # /bin/sh.  The following file(s) will be extracted:
  14. #    percentmem.c
  15. #    prcmd.c
  16. #    prcpu.c
  17. #    prheader.c
  18. #    printall.c
  19. #    printproc.c
  20. #    prsummary.c
  21. #    readstatus.c
  22. #    selectproc.c
  23. #    selecttty.c
  24. #    sps.h
  25. #    sps.l
  26. #    stream.c
  27. #    termwidth.c
  28. #    ttystatus.c
  29. #    vmstat.c
  30. #    waitingfor.c
  31. #
  32. #
  33. # This archive was generated on Mon Aug  6 17:54:08 MET DST 1990
  34. #
  35. #
  36. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  37. if [ -f 'percentmem.c' -a "${1}" != "-c" ] ; then
  38.     echo shar: Won\'t overwrite existing file "percentmem.c"
  39.     exit 2
  40. fi
  41. echo x - percentmem.c
  42. sed -e 's/^X//' > percentmem.c << '---END-OF-percentmem.c---'
  43. X# ifndef lint
  44. Xstatic char SccsId[] =  "@(#)percentmem.c    1.1\t10/1/88" ;
  45. X# endif
  46. X
  47. X# include       "sps.h"
  48. X# ifndef SUNOS40
  49. X# include       <h/text.h>
  50. X# endif
  51. X# ifdef BSD42
  52. X# include    <machine/pte.h>
  53. X# else
  54. X# include       <h/pte.h>
  55. X# include       <h/vmparam.h>
  56. X# endif
  57. X# include       <h/vmmac.h>
  58. X
  59. X/* PERCENTMEM - Returns the percentage of real memory used by this process */
  60. Xdouble  percentmem ( p )
  61. X
  62. Xregister struct process         *p ;
  63. X
  64. X{
  65. X# ifndef SUNOS40
  66. X    register struct text    *tp ;
  67. X# endif
  68. X    int                     szptudot ;
  69. X    double                  fracmem ;
  70. X    extern struct info      Info ;
  71. X
  72. X# ifdef SUNOS40
  73. X    if ( !(p->pr_p.p_flag & SLOAD) )
  74. X        return ( 0.0 ) ;
  75. X    szptudot = UPAGES ;
  76. X    fracmem = ( (double)p->pr_p.p_rssize + szptudot ) ;
  77. X# else
  78. X    tp = p->pr_p.p_textp ;
  79. X    if ( !(p->pr_p.p_flag & SLOAD) || !tp )
  80. X        return ( 0.0 ) ;
  81. X    szptudot = UPAGES + clrnd( ctopt( p->pr_p.p_dsize + p->pr_p.p_ssize ) );
  82. X    fracmem = ( (double)p->pr_p.p_rssize + szptudot ) / CLSIZE ;
  83. X    if ( tp->x_ccount )
  84. X        fracmem += ((double)tp->x_rssize)/CLSIZE/tp->x_ccount ;
  85. X# endif
  86. X    return ( 100.0 * fracmem / (double)Info.i_ecmx ) ;
  87. X}
  88. ---END-OF-percentmem.c---
  89. LEN=`wc -c < percentmem.c`
  90. if [ $LEN !=  1112 ] ; then
  91.     echo shar: File "percentmem.c" was $LEN, should have been 1112 bytes
  92. fi
  93. if [ -f 'prcmd.c' -a "${1}" != "-c" ] ; then
  94.     echo shar: Won\'t overwrite existing file "prcmd.c"
  95.     exit 2
  96. fi
  97. echo x - prcmd.c
  98. sed -e 's/^X//' > prcmd.c << '---END-OF-prcmd.c---'
  99. X# ifndef lint
  100. Xstatic char SccsId[] =  "@(#)prcmd.c    1.1\t10/1/88" ;
  101. X# endif
  102. X
  103. X# include       "sps.h"
  104. X# include       "flags.h"
  105. X
  106. X/* PRCMD - Prints the command arguments according to the switches */
  107. Xprcmd ( p, lpad, width )
  108. X
  109. Xregister struct process         *p ;
  110. Xint                             lpad ;
  111. Xint                             width ;
  112. X
  113. X{
  114. X    extern struct flags     Flg ;
  115. X    extern unsigned         Termwidth ;
  116. X
  117. X    printf( "%*d ", lpad, p->pr_p.p_pid ) ;
  118. X    if ( Flg.flg_f )
  119. X    {
  120. X        printf( "%5d ", p->pr_p.p_ppid ) ;
  121. X        width -= 6 ;
  122. X    }
  123. X    if ( Flg.flg_g )
  124. X    {
  125. X        printf( "%5d ", p->pr_p.p_pgrp ) ;
  126. X        width -= 6 ;
  127. X    }
  128. X    width += Termwidth ;
  129. X    if ( Flg.flg_w )
  130. X        printf( "%s\n", p->pr_cmd ) ;
  131. X    else if ( width > 0 )
  132. X        printf( "%-.*s\n", width, p->pr_cmd ) ;
  133. X    if ( p->pr_csaved )
  134. X        free( p->pr_cmd ) ;
  135. X}
  136. ---END-OF-prcmd.c---
  137. LEN=`wc -c < prcmd.c`
  138. if [ $LEN !=  785 ] ; then
  139.     echo shar: File "prcmd.c" was $LEN, should have been 785 bytes
  140. fi
  141. if [ -f 'prcpu.c' -a "${1}" != "-c" ] ; then
  142.     echo shar: Won\'t overwrite existing file "prcpu.c"
  143.     exit 2
  144. fi
  145. echo x - prcpu.c
  146. sed -e 's/^X//' > prcpu.c << '---END-OF-prcpu.c---'
  147. X# ifndef lint
  148. Xstatic char SccsId[] =  "@(#)prcpu.c    1.1\t10/1/88" ;
  149. X# endif
  150. X
  151. X# include       "sps.h"
  152. X
  153. X# ifdef BSD42
  154. X
  155. X/* PRCPU - Print cpu time */
  156. Xprcpu ( time, utime )
  157. X
  158. Xregister time_t                 time ;
  159. Xtime_t                          utime ;
  160. X
  161. X{
  162. X    time += utime / 1000000 ;
  163. X    utime %= 1000000 ;
  164. X    if ( time < 0L )
  165. X    {       /* Ignore negative times */
  166. X        printf( "     " ) ;     
  167. X        return ;
  168. X    }
  169. X    if ( time < 60L*10L )
  170. X    {       /* Print as seconds if less than 1000 seconds */
  171. X        printf( "%3d.%1d", (int)time, (int)utime/100000 ) ;
  172. X        return ;
  173. X    }
  174. X    /* Print as minutes if less than 10 hours ; print as hours if less than
  175. X       10 days, else print as days. */
  176. X    if ( time < 60L*60L*10L )               
  177. X        printf( "%3D M", time/60L ) ;
  178. X    else if ( time < 24L*60L*60L*10L )
  179. X        printf( "%3D H", time/60L/60L ) ;
  180. X    else
  181. X        printf( "%3D D", time/60L/60L/24L ) ;
  182. X}
  183. X
  184. X# else
  185. X
  186. X/* PRCPU - Print cpu time */
  187. Xprcpu ( time )
  188. X
  189. Xregister time_t                 time ;
  190. X
  191. X{
  192. X    extern struct info      Info ;
  193. X
  194. X    if ( time < 0L )
  195. X    {       /* Ignore negative times */
  196. X        printf( "     " ) ;     
  197. X        return ;
  198. X    }
  199. X    if ( time < Info.i_hz*60L*10L )
  200. X    {       /* Less than 10 minutes */
  201. X        printf( "%3D.%1D", time/Info.i_hz,
  202. X            (time % Info.i_hz / (Info.i_hz/10L)) ) ;
  203. X        return ;
  204. X    }
  205. X    /* If less than 10 hours, print as minutes */
  206. X    time /= Info.i_hz ;
  207. X    /* Print as minutes if less than 10 hours ; print as hours if less than
  208. X       10 days, else print as days. */
  209. X    if ( time < 60L*60L*10L )               
  210. X        printf( "%3D M", time/60L ) ;
  211. X    else if ( time < 24L*60L*60L*10L )
  212. X        printf( "%3D H", time/60L/60L ) ;
  213. X    else
  214. X        printf( "%3D D", time/60L/60L/24L ) ;
  215. X}
  216. X
  217. X# endif
  218. ---END-OF-prcpu.c---
  219. LEN=`wc -c < prcpu.c`
  220. if [ $LEN !=  1614 ] ; then
  221.     echo shar: File "prcpu.c" was $LEN, should have been 1614 bytes
  222. fi
  223. if [ -f 'prheader.c' -a "${1}" != "-c" ] ; then
  224.     echo shar: Won\'t overwrite existing file "prheader.c"
  225.     exit 2
  226. fi
  227. echo x - prheader.c
  228. sed -e 's/^X//' > prheader.c << '---END-OF-prheader.c---'
  229. X# ifndef lint
  230. Xstatic char SccsId[] =  "@(#)prheader.c    1.1\t10/1/88" ;
  231. X# endif
  232. X
  233. X# include       "sps.h"
  234. X# include       "flags.h"
  235. X
  236. X/* PRHEADER - Print a header according to the switches */
  237. Xprheader ()
  238. X{
  239. X    extern struct flags     Flg ;
  240. X
  241. X    printf( "Ty User    %s Proc#", Flg.flg_v ?
  242. X# ifdef SUNOS40
  243. X# ifdef OLDSTATS
  244. X        " Status Fl Nice Virt Res %M  Time Child %C" :
  245. X# else
  246. X        " Status Fl Nice Prv  Shr  Res %M  Time Child %C" :
  247. X# endif
  248. X# else
  249. X        " Status Fl Nice Virtual Resident %M  Time Child %C" :
  250. X# endif
  251. X        Flg.flg_d ?
  252. X        "  Files    PageFaults Swap BlockI/O Kbytsecs" : "" ) ;
  253. X    if ( Flg.flg_f )
  254. X        printf( " Ppid#" ) ;
  255. X    if ( Flg.flg_g )
  256. X        printf( " Pgrp#" ) ;
  257. X    printf( " Command\n" ) ;
  258. X}
  259. ---END-OF-prheader.c---
  260. LEN=`wc -c < prheader.c`
  261. if [ $LEN !=  683 ] ; then
  262.     echo shar: File "prheader.c" was $LEN, should have been 683 bytes
  263. fi
  264. if [ -f 'printall.c' -a "${1}" != "-c" ] ; then
  265.     echo shar: Won\'t overwrite existing file "printall.c"
  266.     exit 2
  267. fi
  268. echo x - printall.c
  269. sed -e 's/^X//' > printall.c << '---END-OF-printall.c---'
  270. X# ifndef lint
  271. Xstatic char SccsId[] =  "@(#)printall.c    1.1\t10/1/88" ;
  272. X# endif
  273. X
  274. X# include       <stdio.h>
  275. X# include       "sps.h"
  276. X
  277. X/* PRINTALL - Recursively print the process tree. */
  278. Xprintall ( p, md )
  279. X
  280. Xregister struct process         *p ;
  281. Xregister int                    md ;
  282. X
  283. X{
  284. X    while ( p )
  285. X    {       /* Print this process */
  286. X        printproc( p, md ) ;    
  287. X        (void)fflush( stdout ) ;
  288. X        /* Print child processes */
  289. X        printall( p->pr_child, md+1 ) ;
  290. X        /* Print brother processes */
  291. X        p = p->pr_sibling ;     
  292. X    }
  293. X}
  294. ---END-OF-printall.c---
  295. LEN=`wc -c < printall.c`
  296. if [ $LEN !=  509 ] ; then
  297.     echo shar: File "printall.c" was $LEN, should have been 509 bytes
  298. fi
  299. if [ -f 'printproc.c' -a "${1}" != "-c" ] ; then
  300.     echo shar: Won\'t overwrite existing file "printproc.c"
  301.     exit 2
  302. fi
  303. echo x - printproc.c
  304. sed -e 's/^X//' > printproc.c << '---END-OF-printproc.c---'
  305. X# ifndef lint
  306. Xstatic char SccsId[] =  "@(#)printproc.c    1.2\t8/2/90" ;
  307. X# endif
  308. X
  309. X# include       "sps.h"
  310. X# include       "flags.h"
  311. X# ifndef SUNOS40
  312. X# include       <h/text.h>
  313. X# endif
  314. X
  315. X# ifdef SUNOS40
  316. X#  ifdef OLDSTATS
  317. X#   define OFFSET 8
  318. X#  else
  319. X#   define OFFSET 3
  320. X#  endif
  321. X# else
  322. X#   define OFFSET 0
  323. X# endif
  324. X
  325. X/* PRINTPROC - Pretty print a process according to the switches. */
  326. Xprintproc ( p, md )
  327. X
  328. Xregister struct process         *p ;            
  329. Xint                             md ;            
  330. X
  331. X{
  332. X    register char           *chp ;
  333. X# ifndef SUNOS40
  334. X    register struct text    *tp ;
  335. X# endif
  336. X    register struct hashtab *hp ;
  337. X    char                    chbuf[10] ;
  338. X    time_t                  time ;
  339. X    time_t                  chtime ;
  340. X# ifdef BSD42
  341. X    time_t                  utime ;
  342. X    time_t                  uchtime ;
  343. X# endif
  344. X    extern short            Lastuid, Lastpgrp ;
  345. X    extern struct flags     Flg ;
  346. X    char                    *waitingfor() ;
  347. X    struct hashtab          *hashuid() ;
  348. X    double                  percentmem() ;
  349. X
  350. X    /* List tty name and foreground/background/detached information */
  351. X    printf( "%2.2s%c", p->pr_tty->l_name,
  352. X# ifdef SDETACH
  353. X        !p->pr_p.p_pgrp ? ' ' : p->pr_p.p_flag & SDETACH ? '_' :
  354. X        p->pr_p.p_pgrp == p->pr_tty->l_pgrp ? '.' : ' ' ) ;
  355. X# else
  356. X        !p->pr_p.p_pgrp || p->pr_p.p_pgrp != p->pr_tty->l_pgrp ?
  357. X# ifdef SPGLDR
  358. X        p->pr_p.p_flag & SPGLDR ? '-' :
  359. X# endif
  360. X           ' ' :
  361. X# ifdef SPGLDR
  362. X        p->pr_p.p_flag & SPGLDR ? '+' :
  363. X# endif
  364. X           '.' ) ;
  365. X# endif
  366. X    hp = hashuid( (int)p->pr_p.p_uid ) ;
  367. X    if ( !md  )                             
  368. X    {       /* If a top-level process, list the user name */
  369. X        if ( hp )
  370. X            printf( "%-8.8s ", hp->h_uname ) ;
  371. X        else
  372. X            printf( "user%-4.4d ", p->pr_p.p_uid ) ;
  373. X    }
  374. X    else                                    
  375. X    {       /* Usually list an asterisk for a child process */
  376. X        md = md > 8 ? 8 : md ;
  377. X        printf( "%*s%c", md, "",
  378. X            p->pr_p.p_pgrp == Lastpgrp ? '|' : '*' ) ;      
  379. X        /* But beware of setuid processes */
  380. X        md = 8 - md ;
  381. X        if ( p->pr_p.p_uid == Lastuid )
  382. X            printf( "%-*.*s", md, md, "" ) ;
  383. X        else if ( hp )
  384. X            printf( "%-*.*s", md, md, hp->h_uname ) ;
  385. X        else
  386. X        {
  387. X            md -= 4 ;
  388. X            printf( "user%-*.*d", md, md, p->pr_p.p_uid ) ;
  389. X        }
  390. X    }
  391. X    Lastuid = p->pr_p.p_uid ;
  392. X    Lastpgrp = p->pr_p.p_pgrp ;
  393. X    if ( Flg.flg_d )                        
  394. X    {       /* List disc I/O and paging information */
  395. X        if ( !p->pr_upag || p->pr_p.p_stat == SZOMB )
  396. X        {
  397. X            prcmd( p, 49, -63 ) ;
  398. X            return ;
  399. X        }
  400. X        printf( "%2d %8d+%8d %4d %8d %8D ",
  401. X            p->pr_files,
  402. X# ifdef BSD42
  403. X            p->pr_rself.ru_majflt,
  404. X            p->pr_rself.ru_minflt,
  405. X            p->pr_rself.ru_nswap,
  406. X            p->pr_rself.ru_inblock + p->pr_rself.ru_oublock,
  407. X            KBYTES( p->pr_rself.ru_idrss + p->pr_rself.ru_isrss
  408. X                + p->pr_rself.ru_ixrss ) ) ;
  409. X# else
  410. X            p->pr_vself.vm_majflt,
  411. X            p->pr_vself.vm_minflt,
  412. X            p->pr_vself.vm_nswap,
  413. X            p->pr_vself.vm_inblk + p->pr_vself.vm_oublk,
  414. X            KBYTES( (p->pr_vself.vm_idsrss
  415. X                + p->pr_vself.vm_ixrss) / Info.i_hz ) ) ;
  416. X# endif
  417. X        prcmd( p, 5, -63 ) ;
  418. X        return ;
  419. X    }
  420. X    if ( !Flg.flg_v )                       
  421. X    {       /* Not verbose so just list command arguments */
  422. X        prcmd( p, 5, -19 ) ;
  423. X        return ;
  424. X    }
  425. X    /* Arrive here if being verbose ; list cpu information */
  426. X    switch ( p->pr_p.p_stat )               
  427. X    {                                       
  428. X        case SSLEEP :
  429. X        case SWAIT :
  430. X        case SIDL :
  431. X            /* Determine why a process should be in a wait state */
  432. X            chp = waitingfor( p ) ;
  433. X            break ;
  434. X        case SRUN :
  435. X            chp = "run" ;
  436. X            break ;
  437. X        case SZOMB :
  438. X            chp = "exit" ;
  439. X            break ;
  440. X        case SSTOP :
  441. X            chp = "stop" ;
  442. X            break ;
  443. X    }
  444. X    /* If the process is loaded, list the status information in capitals */
  445. X    printf( "%-6.6s ", p->pr_p.p_flag & SLOAD ?
  446. X        (capitals( chp, chbuf ), chbuf) : chp ) ;
  447. X    /* List process flags */
  448. X    printf( "%c%c%c", p->pr_p.p_flag & SSYS ? 'U' :
  449. X        p->pr_p.p_flag & STRC ? 'T' : ' ',
  450. X        p->pr_p.p_flag & SVFORK ? 'V' :
  451. X        p->pr_p.p_flag & SPHYSIO ? 'I' : ' ',
  452. X        p->pr_p.p_flag & SUANOM ? 'A' :
  453. X        p->pr_p.p_flag & SSEQL ? 'S' : ' ' ) ;
  454. X    /* List process niceness */
  455. X    if ( p->pr_p.p_nice != NZERO )          
  456. X        printf( "%3d ", p->pr_p.p_nice - NZERO ) ;
  457. X    else
  458. X        printf( "    " ) ;
  459. X    if ( p->pr_p.p_stat == SZOMB )
  460. X    {
  461. X        prcmd( p, 41 - OFFSET, OFFSET - 69 ) ;
  462. X        return ;
  463. X    }                                       
  464. X# ifdef SUNOS40
  465. X#  ifdef OLDSTATS
  466. X    /* List process virtual and real sizes */
  467. X    printf( "%4d", KBYTES( p->pr_p.p_dsize + p->pr_p.p_ssize ) ) ;
  468. X#  else
  469. X    /* List process private and shared virtual and real sizes */
  470. X        printf("%4d", KBYTES( p->pr_private ) ) ;
  471. X        printf("+%4d", KBYTES( p->pr_shared ) ) ;
  472. X#  endif
  473. X    printf( " %4d", KBYTES( p->pr_p.p_rssize ) ) ;
  474. X# else
  475. X    /* List process and text virtual sizes */
  476. X    printf( "%4d", KBYTES( p->pr_p.p_dsize + p->pr_p.p_ssize ) ) ;
  477. X    if ( tp = p->pr_p.p_textp )
  478. X        printf( "+%3d ", KBYTES( tp->x_size ) ) ;
  479. X    else
  480. X        printf( "     " ) ;
  481. X    /* List process and text real sizes */
  482. X    printf( "%4d", KBYTES( p->pr_p.p_rssize ) ) ;
  483. X    if ( tp )
  484. X        printf( "+%3d", KBYTES( tp->x_rssize ) ) ;
  485. X    else
  486. X        printf( "    " ) ;
  487. X# endif
  488. X    printf( " %2.0f ", percentmem( p ) ) ;
  489. X    /* List information obtained from the upage. This includes the process
  490. X       times and command arguments. */
  491. X    if ( !p->pr_upag )
  492. X    {
  493. X        prcmd( p, 20, OFFSET - 69 ) ;
  494. X        return ;
  495. X    }                                       
  496. X    /* List process time information */
  497. X# ifdef BSD42
  498. X    time   = Flg.flg_q ? p->pr_rself.ru_utime.tv_sec :
  499. X         p->pr_rself.ru_utime.tv_sec + p->pr_rself.ru_stime.tv_sec ;
  500. X    utime  = Flg.flg_q ? p->pr_rself.ru_utime.tv_usec :
  501. X         p->pr_rself.ru_utime.tv_usec + p->pr_rself.ru_stime.tv_usec ;
  502. X    chtime = Flg.flg_q ? p->pr_rchild.ru_utime.tv_sec :
  503. X         p->pr_rchild.ru_utime.tv_sec + p->pr_rchild.ru_stime.tv_sec ;
  504. X    uchtime = Flg.flg_q ? p->pr_rchild.ru_utime.tv_usec :
  505. X         p->pr_rchild.ru_utime.tv_usec + p->pr_rchild.ru_stime.tv_usec ;
  506. X    prcpu( time, utime ) ;
  507. X    if ( chtime != 0L )
  508. X    {
  509. X        printf( "+" ) ;
  510. X        prcpu( chtime, uchtime ) ;
  511. X    }
  512. X# else
  513. X    time   = Flg.flg_q ? p->pr_vself.vm_utime :
  514. X         p->pr_vself.vm_utime + p->pr_vself.vm_stime ;
  515. X    chtime = Flg.flg_q ? p->pr_vchild.vm_utime :
  516. X         p->pr_vchild.vm_utime + p->pr_vchild.vm_stime ;
  517. X    prcpu( time ) ;
  518. X    if ( chtime != 0L )
  519. X    {
  520. X        printf( "+" ) ;
  521. X        prcpu( chtime ) ;
  522. X    }
  523. X# endif
  524. X    else
  525. X        printf( "      " ) ;
  526. X# ifdef BSD42
  527. X    if ( time || utime )
  528. X# else
  529. X    if ( time )
  530. X# endif
  531. X# ifdef SUN
  532. X        printf( " %2.0f ", (double)p->pr_p.p_pctcpu * 100.0/FSCALE ) ;
  533. X# else
  534. X#  ifdef DEC3100
  535. X        printf( " %2.0f ", p->pr_p.p_pctcpu ) ;
  536. X#  else
  537. X        printf( " %2.0f ", p->pr_p.p_pctcpu * 100.0 ) ;
  538. X#  endif DEC3100
  539. X# endif SUN
  540. X    else
  541. X        printf( "    " ) ;
  542. X    /* Finally, list the process command arguments. */
  543. X    prcmd( p, 5, OFFSET - 69 ) ;                    
  544. X}
  545. X
  546. X/* CAPITALS - Converts letters in `chp' to upper-case in buffer `buf'. */
  547. Xcapitals ( chp, buf )
  548. X
  549. Xregister char                   *chp ;
  550. Xregister char                   *buf ;
  551. X
  552. X{
  553. X    while ( *buf = *chp++ )
  554. X    {
  555. X        if ( 'a' <= *buf && *buf <= 'z' )
  556. X            *buf -= 'a' - 'A' ;
  557. X        buf++ ;
  558. X    }
  559. X}
  560. ---END-OF-printproc.c---
  561. LEN=`wc -c < printproc.c`
  562. if [ $LEN !=  6875 ] ; then
  563.     echo shar: File "printproc.c" was $LEN, should have been 6875 bytes
  564. fi
  565. if [ -f 'prsummary.c' -a "${1}" != "-c" ] ; then
  566.     echo shar: Won\'t overwrite existing file "prsummary.c"
  567.     exit 2
  568. fi
  569. echo x - prsummary.c
  570. sed -e 's/^X//' > prsummary.c << '---END-OF-prsummary.c---'
  571. X# ifndef lint
  572. Xstatic char SccsId[] =  "@(#)prsummary.c    1.1\t10/1/88" ;
  573. X# endif
  574. X
  575. X# include       "sps.h"
  576. X
  577. X/* PRSUMMARY - Print the summarising information */
  578. Xprsummary ()
  579. X{
  580. X    extern struct summary   Summary ;
  581. X
  582. X    printf(
  583. X"%D (%Dk) processes, %D (%Dk) busy, %D (%Dk) loaded, %D (%Dk) swapped\n",
  584. X        Summary.sm_ntotal, KBYTES( Summary.sm_ktotal ),
  585. X        Summary.sm_nbusy, KBYTES( Summary.sm_kbusy ),
  586. X        Summary.sm_nloaded, KBYTES( Summary.sm_kloaded ),
  587. X        Summary.sm_nswapped, KBYTES( Summary.sm_kswapped ) ) ;
  588. X    Summary.sm_ntotal = 0L ;
  589. X    Summary.sm_ktotal = 0L ;
  590. X    Summary.sm_nbusy = 0L ;
  591. X    Summary.sm_kbusy = 0L ;
  592. X    Summary.sm_nloaded = 0L ;
  593. X    Summary.sm_kloaded = 0L ;
  594. X    Summary.sm_nswapped = 0L ;
  595. X    Summary.sm_kswapped = 0L ;
  596. X}
  597. ---END-OF-prsummary.c---
  598. LEN=`wc -c < prsummary.c`
  599. if [ $LEN !=  712 ] ; then
  600.     echo shar: File "prsummary.c" was $LEN, should have been 712 bytes
  601. fi
  602. if [ -f 'readstatus.c' -a "${1}" != "-c" ] ; then
  603.     echo shar: Won\'t overwrite existing file "readstatus.c"
  604.     exit 2
  605. fi
  606. echo x - readstatus.c
  607. sed -e 's/^X//' > readstatus.c << '---END-OF-readstatus.c---'
  608. X# ifndef lint
  609. Xstatic char SccsId[] =  "@(#)readstatus.c    1.1\t10/1/88" ;
  610. X# endif
  611. X
  612. X# include       "sps.h"
  613. X# ifndef SUNOS40
  614. X# include       <h/text.h>
  615. X# endif
  616. X
  617. X/* READSTATUS - Reads the kernel memory for current processes and texts */
  618. X# ifdef SUNOS40
  619. Xreadstatus ( process )
  620. X
  621. Xregister struct process         *process ;
  622. X
  623. X# else
  624. X
  625. Xreadstatus ( process, text )
  626. X
  627. Xregister struct process         *process ;
  628. Xstruct text                     *text ;
  629. X
  630. X# endif
  631. X{
  632. X    register struct proc    *p ;
  633. X    register struct proc    *p0 ;
  634. X    register struct process *pr ;
  635. X    int                     size ;
  636. X    extern struct info      Info ;
  637. X    char                    *getcore() ;
  638. X
  639. X# ifndef SUNOS40
  640. X    /* Read current text information */
  641. X    size = Info.i_ntext * sizeof( struct text ) ;
  642. X    if ( getkmem( (long)Info.i_text0, (char*)text, size ) != size )
  643. X        prexit( "sps - Can't read system text table\n" ) ;
  644. X# endif
  645. X    /* Read current process information */
  646. X    size = Info.i_nproc * sizeof( struct proc ) ;
  647. X    p0 = (struct proc*)getcore( size ) ;
  648. X    if ( getkmem( (long)Info.i_proc0, (char*)p0, size ) != size )
  649. X        prexit( "sps - Can't read system process table\n" ) ;
  650. X    /* Copy process information into our own array */
  651. X    for ( p = p0, pr = process ; pr < &process[ Info.i_nproc ] ; p++, pr++ )
  652. X        pr->pr_p = *p ;
  653. X    free( (char*)p0 ) ;
  654. X}
  655. ---END-OF-readstatus.c---
  656. LEN=`wc -c < readstatus.c`
  657. if [ $LEN !=  1281 ] ; then
  658.     echo shar: File "readstatus.c" was $LEN, should have been 1281 bytes
  659. fi
  660. if [ -f 'selectproc.c' -a "${1}" != "-c" ] ; then
  661.     echo shar: Won\'t overwrite existing file "selectproc.c"
  662.     exit 2
  663. fi
  664. echo x - selectproc.c
  665. sed -e 's/^X//' > selectproc.c << '---END-OF-selectproc.c---'
  666. X# ifndef lint
  667. Xstatic char SccsId[] =  "@(#)selectproc.c    1.2\t6/15/90" ;
  668. X# endif
  669. X
  670. X# include       "sps.h"
  671. X# include       "flags.h"
  672. X# ifdef USELOGINUID
  673. X# include    <pwd.h>
  674. X# endif USELOGINUID
  675. X
  676. X/*
  677. X** SELECTPROC - Given a process structure, this procedure decides whether
  678. X** the process is a candidate for printing.
  679. X*/
  680. Xselectproc ( p, process, thisuid )
  681. X
  682. Xregister struct process         *p ;            
  683. Xregister struct process         *process ;      
  684. Xint                thisuid ;
  685. X
  686. X{
  687. X    register union flaglist *fp ;
  688. X    register struct process *pp ;
  689. X#ifdef USELOGINUID
  690. X    char            *username ;
  691. X    struct passwd        *pw ;
  692. X    char            *getlogin() ;
  693. X    struct passwd        *getpwnam() ;
  694. X#endif USELOGINUID
  695. X    extern struct flags     Flg ;
  696. X
  697. X    /* Flg.flg_AZ is an internal flag set if one of flags `A' to `Z'
  698. X       was specified. If this is not set, a process is listed only
  699. X       if it or one of its ancestors belongs to the invoking user. */
  700. X    if ( !Flg.flg_AZ )
  701. X    {
  702. X#ifdef USELOGINUID
  703. X        thisuid = (username = getlogin())
  704. X            && (pw = getpwnam( username )) ? pw->pw_uid : getuid() ;
  705. X#endif USELOGINUID
  706. X        for ( pp = p ; pp > &process[1] ; pp = pp->pr_pptr )
  707. X            if ( thisuid == pp->pr_p.p_uid )
  708. X                return ( 1 ) ;
  709. X    }
  710. X    if ( Flg.flg_A )
  711. X        return ( 1 ) ;
  712. X    if ( Flg.flg_P )
  713. X        for ( fp = Flg.flg_Plist ; fp->f_pid >= 0 ; fp++ )
  714. X            if ( fp->f_pid == p->pr_p.p_pid )
  715. X                return ( 1 ) ;
  716. X    if ( Flg.flg_U )
  717. X        for ( pp = p ; pp > &process[1] ; pp = pp->pr_pptr )
  718. X            for ( fp = Flg.flg_Ulist ; fp->f_uid >= 0 ; fp++ )
  719. X                if ( fp->f_uid == pp->pr_p.p_uid )
  720. X                    return ( 1 ) ;
  721. X    switch ( p->pr_p.p_stat )
  722. X    {
  723. X        case SRUN :
  724. X            if ( Flg.flg_B )
  725. X# ifdef SUNOS40
  726. X                /* Ignore the idle processes */
  727. X                return ( p->pr_p.p_pid != 3
  728. X                    && p->pr_p.p_pid != 4 ) ;
  729. X# else
  730. X                return ( 1 ) ;
  731. X# endif SUNOS40
  732. X            break ;
  733. X        case SSLEEP :
  734. X            if ( Flg.flg_B
  735. X            &&   p->pr_p.p_pri < PZERO && p->pr_p.p_pid > MSPID )
  736. X# ifdef SUNOS40
  737. X                /* Ignore the idle processes */
  738. X                return ( p->pr_p.p_pid != 3
  739. X                    && p->pr_p.p_pid != 4 ) ;
  740. X# else
  741. X                return ( 1 ) ;
  742. X# endif SUNOS40
  743. X        case SWAIT :
  744. X        case SIDL :
  745. X            if ( Flg.flg_W )
  746. X                return ( 1 ) ;
  747. X            break ;
  748. X        case SSTOP :
  749. X            if ( Flg.flg_S )
  750. X                return ( 1 ) ;
  751. X            break ;
  752. X        case SZOMB :
  753. X            if ( Flg.flg_Z )
  754. X                return ( 1 ) ;
  755. X            break ;
  756. X        default :
  757. X            break ;
  758. X    }
  759. X    return ( 0 ) ;
  760. X}
  761. ---END-OF-selectproc.c---
  762. LEN=`wc -c < selectproc.c`
  763. if [ $LEN !=  2248 ] ; then
  764.     echo shar: File "selectproc.c" was $LEN, should have been 2248 bytes
  765. fi
  766. if [ -f 'selecttty.c' -a "${1}" != "-c" ] ; then
  767.     echo shar: Won\'t overwrite existing file "selecttty.c"
  768.     exit 2
  769. fi
  770. echo x - selecttty.c
  771. sed -e 's/^X//' > selecttty.c << '---END-OF-selecttty.c---'
  772. X# ifndef lint
  773. Xstatic char SccsId[] =  "@(#)selecttty.c    1.1\t10/1/88" ;
  774. X# endif
  775. X
  776. X# include       "sps.h"
  777. X# include       "flags.h"
  778. X
  779. X/* SELECTTTY - Decides whether this process is interesting for its tty */
  780. Xselecttty ( p )
  781. X
  782. Xregister struct process         *p ;
  783. X
  784. X{
  785. X    register union flaglist *fp ;
  786. X    extern struct flags     Flg ;
  787. X
  788. X    for ( fp = Flg.flg_Tlist ; fp->f_ttyline ; fp++ )
  789. X        if ( fp->f_ttyline == p->pr_tty )
  790. X            return ( 1 ) ;
  791. X    return ( 0 ) ;
  792. X}
  793. ---END-OF-selecttty.c---
  794. LEN=`wc -c < selecttty.c`
  795. if [ $LEN !=  448 ] ; then
  796.     echo shar: File "selecttty.c" was $LEN, should have been 448 bytes
  797. fi
  798. if [ -f 'sps.h' -a "${1}" != "-c" ] ; then
  799.     echo shar: Won\'t overwrite existing file "sps.h"
  800.     exit 2
  801. fi
  802. echo x - sps.h
  803. sed -e 's/^X//' > sps.h << '---END-OF-sps.h---'
  804. X# ifndef lint
  805. Xstatic char SpsHId[] =  "@(#)sps.h    1.3\t7/4/90" ;
  806. X# endif
  807. X
  808. X# ifdef SUNOS40
  809. X#  define KERNEL
  810. X# endif SUNOS40
  811. X# include    <h/param.h>
  812. X# undef KERNEL
  813. X# include    <h/dir.h>
  814. X# include    <h/user.h>
  815. X# include    <h/proc.h>
  816. X
  817. X# ifdef SUNOS40
  818. X#  ifndef BSD43
  819. X#   define BSD43
  820. X# endif BSD43
  821. X# endif SUNOS40
  822. X
  823. X/*
  824. X** Maximum # of users to be considered. (Because user names are stored
  825. X** in a hash table, this should probably be at least double the number
  826. X** of actual users defined in /etc/passwd or by the Yellow Pages.)
  827. X*/
  828. X# define    MAXUSERS    100
  829. X/* Maximum # ttys to be considered, plus 1 for the console ... */
  830. X# define    MAXTTYS        97
  831. X
  832. X
  833. X/* Maximum user name length ... */
  834. X# define    UNAMELEN    8
  835. X/* Maximum process-id not to be considered busy ... */
  836. X# define    MSPID        2
  837. X/* # of wait states defined in the `struct info' ... */
  838. X# ifdef NFS
  839. X#  ifdef SUN
  840. X#   define    NWAITSTATE    16
  841. X#  else
  842. X#   define    NWAITSTATE    36
  843. X#  endif SUN
  844. X# else NFS
  845. X#  ifdef ULTRIX20
  846. X#   define    NWAITSTATE    36
  847. X#  else ULTRIX20
  848. X#   define    NWAITSTATE    35
  849. X#  endif ULTRIX20
  850. X# endif NFS
  851. X
  852. X/* Convert clicks to kbytes ... */
  853. X# ifndef PGSHIFT
  854. X#  define    KBYTES( size )    ((size) << 1)
  855. X# else PGSHIFT
  856. X#  if PGSHIFT > 10
  857. X#   define        KBYTES( size )  ((size) << (PGSHIFT - 10))
  858. X#  else
  859. X#   define    KBYTES( size )    ((size) >> (10 - PGSHIFT))
  860. X#  endif
  861. X# endif PGSHIFT
  862. X
  863. X/* Standard files to be examined ... */
  864. X# define    FILE_MEM    "/dev/mem"    /* System physical memory */
  865. X# define    FILE_KMEM    "/dev/kmem"    /* Kernel virtual memory */
  866. X# define    FILE_SWAP    "/dev/drum"    /* Swap/paging device */
  867. X# define    FILE_DEV    "/dev"        /* Directory of tty entries */
  868. X# define    FILE_SYMBOL    "/vmunix"    /* Symbol file for nlist() */
  869. X# define    FILE_INFO    "/tmp/.spsinfo"    /* Sps information file */
  870. X# define    FILE_PASSWD    "/etc/passwd"    /* User database */
  871. X
  872. X/* Structure to hold necessary information concerning a tty ... */
  873. Xstruct ttyline
  874. X{
  875. X    char            l_name[2] ;    /* Tty character name */
  876. X    unsigned short        l_pgrp ;    /* Tty process group */
  877. X# ifdef SUNOS40
  878. X    struct streamtab    *l_addr ;    /* Ptr to streamtab in kmem */
  879. X    struct stdata        *l_stdata ;    /* Ptr to stdata at runtime */
  880. X# else SUNOS40
  881. X    struct tty        *l_addr ;    /* Ptr to tty struct in kmem */
  882. X# endif SUNOS40
  883. X    dev_t            l_dev ;        /* Tty device # */
  884. X} ;
  885. X
  886. X/* Structure holding a single hash table entry ... */
  887. Xstruct hashtab
  888. X{
  889. X    short            h_uid ;        /* Uid of user entry */
  890. X    char            h_uname[ UNAMELEN ] ; /* Corresponding name */
  891. X} ;
  892. X
  893. X/*
  894. X** Format of the standard information file maintained by sps.
  895. X** This structure is filled in at initialisation time and then is read back
  896. X** in whenever sps is invoked.
  897. X** Note that the pointer variables in this structure refer to
  898. X** kernel virtual addresses, not addresses within sps.
  899. X** These variable are typed as such so that pointer arithmetic
  900. X** on the kernel addresses will work correctly.
  901. X*/
  902. Xstruct info
  903. X{    /* Kernel values determining process, tty and upage info ... */
  904. X    struct proc        *i_proc0 ;    /* address of process table */
  905. X    int            i_nproc ;    /* length of process table */
  906. X# ifndef SUNOS40
  907. X    struct text        *i_text0 ;    /* address of text table */
  908. X# endif SUNOS40
  909. X    int            i_ntext ;    /* length of text table */
  910. X# ifdef ULTRIX20
  911. X    struct gnode        *i_inode0 ;    /* address of inode table */
  912. X# else ULTRIX20
  913. X    struct inode        *i_inode0 ;    /* address of inode table */
  914. X# endif ULTRIX20
  915. X    int            i_ninode ;    /* length of inode table */
  916. X    int            i_ecmx ;    /* max physical memory address*/
  917. X# ifndef SUNOS40
  918. X    struct buf        *i_swbuf0 ;    /* address of swap buffers */
  919. X    int            i_nswbuf ;    /* # swap buffers */
  920. X    struct buf        *i_buf0 ;    /* address of i/o buffers */
  921. X    int            i_nbuf ;    /* # i/o buffers */
  922. X    struct pte        *i_usrptmap ;    /* page table map */
  923. X    struct pte        *i_usrpt ;    /* page table map */
  924. X# endif SUNOS40
  925. X    struct cdevsw        *i_cdevsw ;    /* device switch to find ttys */
  926. X# ifdef BSD42
  927. X#  ifdef NFS
  928. X    struct dquot        *i_quota0 ;    /* disc quota structures */
  929. X#  else NFS
  930. X    struct quota        *i_quota0 ;    /* disc quota structures */
  931. X#  endif NFS
  932. X    int            i_nquota ;    /* # quota structures */
  933. X    int            i_dmmin ;    /* The start of the disc map */
  934. X    int            i_dmmax ;    /* The end of the disc map */
  935. X    struct mbuf        *i_mbutl ;    /* Start of mbuf area */
  936. X# else BSD42
  937. X    int            i_hz ;        /* Clock rate */
  938. X# endif BSD42
  939. X# ifdef CHAOS
  940. X    caddr_t            i_Chconntab ;    /* Chaos connection table */
  941. X# endif
  942. X    /* Kernel addresses are associated with process wait states ... */
  943. X    caddr_t            i_waitstate[ NWAITSTATE ] ;
  944. X    /* User names, stored in a hash table ... */
  945. X    struct hashtab        i_hnames[ MAXUSERS ] ;
  946. X    /* Tty device info ... */
  947. X    struct ttyline        i_ttyline[ MAXTTYS ] ;
  948. X# ifdef SUNOS40
  949. X    struct seg_ops        *i_segvn_ops ;    /* ptr to vnode segment ops */
  950. X    struct pty        *i_ptybase ;
  951. X    int            i_npty ;
  952. X#  ifdef SUNOS41
  953. X    struct strstat        *i_strst;
  954. X    struct stdata        *i_allstream;
  955. X#  else SUNOS41
  956. X    struct stdata        *i_streams ;    /* streams list */
  957. X    struct stdata        *i_streamsNSTREAMS ;
  958. X#  endif SUNOS41
  959. X    caddr_t            i_sysbase ;
  960. X# endif SUNOS40
  961. X} ;
  962. X
  963. X/*
  964. X** The symbol structure cross-references values read from the kernel with
  965. X** their place in the info structure, and if such a value is associated with
  966. X** a process wait state or not.
  967. X*/
  968. Xstruct symbol
  969. X{
  970. X    char            *s_kname ;    /* Kernel symbol name */
  971. X    char            s_indirect ;    /* Value requires indirection */
  972. X    caddr_t            *s_info ;    /* Corresponding info address */
  973. X    char            *s_wait ;    /* Reason for wait, if any */
  974. X} ;
  975. X
  976. X/* The `user' structure obtained from /dev/mem or /dev/swap ... */
  977. Xunion userstate
  978. X{
  979. X    struct user        u_us ;
  980. X    char            u_pg[ UPAGES ][ NBPG ] ;
  981. X} ;
  982. X
  983. X/* Information concerning each process filled from /dev/kmem ... */
  984. Xstruct process
  985. X{
  986. X    struct proc        pr_p ;        /* struct proc from /dev/kmem */
  987. X    struct process        *pr_plink ;    /* Normalised ptrs from above */
  988. X    struct process        *pr_sibling ;    /* Ptr to sibling process */
  989. X    struct process        *pr_child ;    /* Ptr to child process */
  990. X    struct process        *pr_pptr ;    /* Ptr to parent process */
  991. X# ifdef BSD42
  992. X    struct rusage        pr_rself ;    /* Read from upage for self */
  993. X    struct rusage        pr_rchild ;    /* ... and the children */
  994. X# else BSD42
  995. X    struct vtimes        pr_vself ;    /* Read from upage for self */
  996. X    struct vtimes        pr_vchild ;    /* ... and the children */
  997. X# endif BSD42
  998. X    int            pr_files ;    /* # open files */
  999. X    struct ttyline        *pr_tty ;    /* Associated tty information */
  1000. X    char            *pr_cmd ;    /* Command args, from upage */
  1001. X    int            pr_upag:1 ;    /* Upage was obtained */
  1002. X    int            pr_csaved:1 ;    /* Cmd args saved by malloc() */
  1003. X# ifdef SUNOS40
  1004. X    unsigned        pr_private ;    /* private pages */
  1005. X    unsigned        pr_shared ;    /* shared pages */
  1006. X# endif SUNOS40
  1007. X} ;
  1008. X
  1009. X/* Structure to hold summarising information ... */
  1010. Xstruct summary
  1011. X{
  1012. X    long            sm_ntotal ;    /* Total # processes */
  1013. X    long            sm_ktotal ;    /* Total virtual memory */
  1014. X    long            sm_nbusy ;    /* # busy processes */
  1015. X    long            sm_kbusy ;    /* Busy virtual memory */
  1016. X    long            sm_nloaded ;    /* # loaded processes */
  1017. X    long            sm_kloaded ;    /* Active resident memory */
  1018. X    long            sm_nswapped ;    /* # swapped processes */
  1019. X    long            sm_kswapped ;    /* Size totally swapped out */
  1020. X} ;
  1021. ---END-OF-sps.h---
  1022. LEN=`wc -c < sps.h`
  1023. if [ $LEN !=  6824 ] ; then
  1024.     echo shar: File "sps.h" was $LEN, should have been 6824 bytes
  1025. fi
  1026. if [ -f 'sps.l' -a "${1}" != "-c" ] ; then
  1027.     echo shar: Won\'t overwrite existing file "sps.l"
  1028.     exit 2
  1029. fi
  1030. echo x - sps.l
  1031. sed -e 's/^X//' > sps.l << '---END-OF-sps.l---'
  1032. X.if n .pl 66
  1033. X.TH SPS 1
  1034. X.SH NAME
  1035. Xsps \ \ \-\ \ \ show process status
  1036. X.SH SYNOPSIS
  1037. X\fBsps\ \fP \ [ \fB\-cdefgijkoqrslvwyABDFNPSTUWZ\fP ]\ \ [
  1038. X\fIprocess\ .\ .\ .\ | tty\ .\ .\ .\ | user\ .\ .\ .\fP ]
  1039. X.SH DESCRIPTION
  1040. X\fISps\fP reports information concerning system processes.
  1041. XIt shows the current state of any process by
  1042. Xlisting information such as ownership, CPU time usage, memory usage
  1043. Xand disc activity.
  1044. X.PP
  1045. X\fISps\fP should be used in preference to \fIps\fP(1)
  1046. Xbecause it is faster and the output is more comprehensive and more
  1047. Xcomprehensible.
  1048. X.SH OPTIONS
  1049. XBy default, \fIsps\fP prints basic information about one's own processes.
  1050. XThe various options described below select other processes or make
  1051. X\fIsps\fP more verbose.
  1052. X.PP
  1053. XUpper case options select processes to be described.
  1054. XLower case options specify the format of the output.
  1055. XFor instance, the options \fBBv\fP specify that \fIsps\fP
  1056. Xshould list ``busy'' processes in a verbose format.
  1057. XUnless there is any conflict, lower case options may be used
  1058. Xinstead of upper case options, and vice versa.
  1059. X.PP
  1060. XThe following options specify the format of the listed output \-
  1061. X.TP 8
  1062. X\fB\-c\fP
  1063. XUse the system's idea of the command, rather than getting the arguments
  1064. Xfrom user space.  While somewhat less informative, this is faster and
  1065. Xmore reliable.
  1066. X.TP
  1067. X\fB\-d\fP
  1068. XList output reflecting how each process affects the
  1069. Xdisc and paging activity of the system.
  1070. X.TP
  1071. X\fB\-e\fP
  1072. XList the environment passed to each process.
  1073. X.TP
  1074. X\fB\-f\fP
  1075. XInclude the process\-id of the parent of each process.
  1076. X.TP
  1077. X\fB\-g\fP
  1078. XInclude the process group of each process.
  1079. X.TP
  1080. X\fB\-o\fP
  1081. XAvoid looking at the swap device (\fB/dev/drum\fP). This tends to make \fIsps\fP
  1082. Xrun faster, although no information concerning swapped processes
  1083. Xcan be obtained.
  1084. X.TP
  1085. X\fB\-q\fP
  1086. XBy default, \fIsps\fP
  1087. Xlists the sum of the user plus system times under the
  1088. X\fITime\fP and \fIChild\fP fields.  This option forces \fIsps\fP
  1089. Xto list only the user times.
  1090. X.TP
  1091. X\fB\-r\fP
  1092. XRepeat the output indefinitely.
  1093. XIf the next argument is numeric, \fIsps\fP repeats the output with that
  1094. Xmany seconds delay between each repetition.
  1095. XOtherwise the output is repeated with no delay.
  1096. X.TP
  1097. X\fB\-l\fP
  1098. X.br
  1099. X.ns
  1100. X.TP
  1101. X\fB\-v\fP
  1102. XList additional information in a verbose format. See below.
  1103. X.TP
  1104. X\fB\-w\fP
  1105. XList output in a wide format.  This option forces \fIsps\fP
  1106. Xto print all the command arguments, even if doing so extends the output
  1107. Xbeyond one line.
  1108. X.TP
  1109. X\fB\-y\fP
  1110. XShow the status of each terminal line.
  1111. X.PP
  1112. XThe following options specify which processes are to be described \-
  1113. X.TP 8
  1114. X\fB\-A\fP
  1115. XList all processes.
  1116. X.TP
  1117. X\fB\-B\fP
  1118. XList busy processes.  A process is considered to be busy
  1119. Xif it is immediately runnable or awaiting a fast event such as disc I/O.
  1120. X.TP
  1121. X\fB\-D\fP
  1122. XList detached processes.
  1123. X.TP
  1124. X\fB\-F\fP
  1125. XList foreground processes.
  1126. X.TP
  1127. X\fB\-N\fP
  1128. XShow no processes at all. Only the summary line is printed.
  1129. X.TP
  1130. X\fB\-P\fP
  1131. XList only processes whose identifiers are specified in the following arguments.
  1132. X.TP
  1133. X\fB\-S\fP
  1134. XList stopped processes.
  1135. X.TP
  1136. X\fB\-T\fP
  1137. XList only processes attached to the following specified terminals.
  1138. X.TP
  1139. X\fB\-U\fP
  1140. XList only processes belonging to the following specified users.
  1141. X.TP
  1142. X\fB\-W\fP
  1143. XList waiting processes.
  1144. X.TP
  1145. X\fB\-Z\fP
  1146. XList zomby (exiting) processes.
  1147. X.PP
  1148. XThe following are miscellaneous options \-
  1149. X.TP 8
  1150. X\fB\-i\fP
  1151. XInitialise \fIsps\fP.
  1152. XThis is necessary if new users are added to the password file,
  1153. Xor if a new version of UNIX is installed.
  1154. XSps builds a new information file summarising pertinent information
  1155. Xread from the password file (\fB/etc/passwd\fP), the executable kernel image
  1156. X(\fB/vmunix\fP) and the directory of tty devices (\fB/dev\fP).
  1157. XSee also the \fB\-j\fP and \fB\-s\fP options.
  1158. X.TP
  1159. X\fB\-j\fP
  1160. XSpecify an information file other than the default (\fB/etc/spsinfo\fP).
  1161. XThe next argument is taken to be the name of a suitable information file.
  1162. XIf the \fB\-i\fP flag is also specified, \fIsps\fP builds a
  1163. Xnew information file with the given name.
  1164. XOtherwise, \fBsps\fP reads previously created summarising information
  1165. Xfrom that file.
  1166. X.TP
  1167. X\fB\-k\fP
  1168. XUse a specific disc file rather than the default physical
  1169. Xmemory (\fB/dev/mem\fP)
  1170. Xand kernel virtual memory (\fB/dev/kmem\fP) files. The next argument is taken
  1171. Xto be the name of a suitable memory dump file.
  1172. XThis flag automatically sets the \fB\-o\fP flag.
  1173. X.TP
  1174. X\fB\-s\fP
  1175. XThis option is used in conjunction with the \fB\-i\fP option.
  1176. XThe next argument is taken to be the name of a suitable kernel executable
  1177. Xfile, rather than the default (\fB/vmunix\fP).
  1178. X\fISps\fP looks at the symbol table of this file to determine
  1179. Xthe virtual addresses of various kernel structures.
  1180. X.SH OUTPUT
  1181. X\fISps\fP produces output in the following fields \-
  1182. X.TP 8
  1183. X\fITy\fP
  1184. XThe terminal identifier to which the process is attached.
  1185. X.IP
  1186. XIf this is followed by an underscore, the process is detached.
  1187. XIf it is followed by a period, the process is running in the foreground.
  1188. XOtherwise the process is running in the background but is still
  1189. Xattached to a terminal.
  1190. X.TP
  1191. X\fIUser\fP
  1192. XThe symbolic name of the process' effective user-id (see \fIexec\fP(2)
  1193. Xand \fIsetuid\fP(2)).
  1194. XThis name is defined by the system password file (\fB/etc/passwd\fP)
  1195. Xwhen \fIsps\fP was last initialised.
  1196. XOtherwise, an asterisk (\fB*\fP) or vertical bar (\fB|\fP) appearing in this
  1197. Xcolumn denotes that the process is an immediate relative of the
  1198. Xpreceding process.
  1199. XA bar is listed, rather than an asterisk, if both processes belong
  1200. Xto the same process group.
  1201. XA user name is listed only if the effective user-id
  1202. Xdiffers from that of the preceding process or if it is a top-level
  1203. Xprocess (immediate offspring of process 1).
  1204. X.TP
  1205. X\fIProc#\fP
  1206. XThe unique process identifier.
  1207. X.TP
  1208. X\fIPpid#\fP
  1209. XThe process-id of the process' parent.
  1210. X.TP
  1211. X\fIPgrp#\fP
  1212. XThe process group to which the process belongs.
  1213. X.TP
  1214. X\fICommand\fP
  1215. XThe command arguments obtained from the process' own address space.
  1216. X(If the command name appears in parentheses, \fIsps\fP
  1217. Xwas unable to locate the arguments in user space and so reports
  1218. Xthe system's idea of the command name.)
  1219. X.PP
  1220. XThe following additional fields are listed when \fIsps\fP
  1221. Xis invoked with one of the \fB\-l\fP or \fB\-v\fP options \-
  1222. X.TP 8
  1223. X\fIStatus\fP
  1224. XThe process' current state.
  1225. XIf this field is listed in upper-case letters, the process is currently
  1226. Xloaded in real memory space ; otherwise it has been swapped out.
  1227. XThe status field may contain one of the following descriptions \-
  1228. X.RS 8
  1229. X.TP 16
  1230. X\fIrun\fP
  1231. XThe process can be run immediately.
  1232. X.TP
  1233. X\fIstop\fP
  1234. XThe process is stopped. See \fIsigvec\fP(2).
  1235. X.TP
  1236. X\fIexit\fP
  1237. XThe process is a zomby.
  1238. X.RE
  1239. X.IP
  1240. XAny other entry in the status field indicates the process is
  1241. Xwaiting for some external event to occur.
  1242. XThis is usually for one of the reasons listed below.
  1243. X(If \fIsps\fP does not know why a process is waiting, it lists
  1244. Xthe hexadecimal address of the process' wait channel,
  1245. Xwith the initial 80000000 trimmed off.)
  1246. XA process may be waiting for one of the following reasons \-
  1247. X.RS 8
  1248. X.TP 16
  1249. X\fIchild\fP
  1250. XThe process is waiting for a child to terminate. See \fIwait\fP(2).
  1251. X.TP
  1252. X\fIpause\fP
  1253. XWaiting for a signal to be received. See \fIsigpause\fP(2).
  1254. X.TP
  1255. X\fIswap\fP
  1256. XWaiting for a page to be swapped in.
  1257. X.TP
  1258. X\fIrswbuf\fP
  1259. XWaiting for a read from the swap device \fB/dev/drum.\fP
  1260. X.TP
  1261. X\fIdiscio\fP
  1262. XWaiting for a disc read or write operation.
  1263. X(Actually, this means that the process is waiting for an operation
  1264. Xthrough the kernel's I/O buffering mechanism to complete, but \fIdiscio\fP
  1265. Xis what is generally meant here).
  1266. X.TP
  1267. X\fIrpipe\fP
  1268. X.br
  1269. X.ns
  1270. X.TP
  1271. X\fIwpipe\fP
  1272. XWaiting for a read from an empty pipe.  Alternatively, the process
  1273. Xis waiting to write to a full pipe. See \fIpipe\fP(2).
  1274. X.TP
  1275. X\fIrsockt\fP
  1276. X.br
  1277. X.ns
  1278. X.TP
  1279. X\fIwsockt\fP
  1280. XWaiting for a read from an empty socket.
  1281. XAlternatively, the process is waiting to write to a full socket (4.[2\-]bsd only).
  1282. X.TP
  1283. X\fIaccept\fP
  1284. XWaiting to accept a stream-based socket connection (4.[2\-]bsd only).
  1285. XSee \fIaccept\fP(2).
  1286. X.TP
  1287. X\fIconnct\fP
  1288. XWaiting to establish a connection through a stream-based socket to a
  1289. Xremote process (4.[2\-]bsd only). See \fIconnect\fP(2).
  1290. X.TP
  1291. X\fIsocket\fP
  1292. XWaiting for some other time-out event on a socket (4.[2\-]bsd only).
  1293. X.TP
  1294. X\fIselect\fP
  1295. XBlocked by a \fIselect\fP(2) system call (4.[2\-]bsd only).
  1296. X.TP
  1297. X\fIrmux\fP
  1298. XWaiting for a read from a multiplexor file (4.1bsd only).
  1299. X.TP
  1300. X\fIinode\fP
  1301. XWaiting for an inode to be allocated or unlocked.
  1302. X.TP
  1303. X\fIexlock\fP
  1304. X.br
  1305. X.ns
  1306. X.TP
  1307. X\fIshlock\fP
  1308. XWaiting for a file to become unlocked. See \fIflock\fP(2).
  1309. X.TP
  1310. X\fIrtty??\fP
  1311. X.br
  1312. X.ns
  1313. X.TP
  1314. X\fIwtty??\fP
  1315. X.br
  1316. X.ns
  1317. X.TP
  1318. X\fIotty??\fP
  1319. XWaiting for a read or write to the specified terminal, or for the terminal
  1320. Xto be switched on. See \fItty\fP(4).
  1321. XAlternatively, waiting for a read or write to the
  1322. Xspecified slave pty device. See \fIpty\fP(4).
  1323. X.TP
  1324. X\fIitty??\fP
  1325. X.br
  1326. X.ns
  1327. XUnder SunOS, waiting perform I/O to an iconified window.
  1328. X.TP
  1329. X\fIrpty??\fP
  1330. X.br
  1331. X.ns
  1332. X.TP
  1333. X\fIwpty??\fP
  1334. XWaiting for a read or write to the specified master pty device.
  1335. XSee \fIpty\fP(4).
  1336. X.TP
  1337. X\fIptrace\fP
  1338. XThis is a parent process tracing its child.
  1339. X.TP
  1340. X\fIvfork\fP
  1341. XThis is a vforking parent process waiting for its child to relinquish
  1342. Xmemory resources. See \fIvfork\fP(2).
  1343. X.TP
  1344. X\fIfloppy\fP
  1345. X.br
  1346. X.ns
  1347. X.TP
  1348. X\fIprintr\fP
  1349. X.br
  1350. X.ns
  1351. X.TP
  1352. X\fIr??buf\fP
  1353. XWaiting for the specified device to complete an I/O operation.
  1354. X.RE
  1355. X.TP 8
  1356. X\fIFl\fP
  1357. XFlags associated with the current state of the process.
  1358. XThese flags may be any of the following \-
  1359. X.RS 8
  1360. X.TP 16
  1361. X\fIU\fP
  1362. XThe process is a UNIX system process.
  1363. X.TP
  1364. X\fIT\fP
  1365. XThe process is being traced or debugged.
  1366. X.TP
  1367. X\fIV\fP
  1368. XThe process is a child currently being vforked. See \fIvfork\fP(2).
  1369. X.TP
  1370. X\fII\fP
  1371. XThe process is undergoing physical I/O.
  1372. X.TP
  1373. X\fIA\fP
  1374. XThe system has detected, or the user has warned of
  1375. Xanomalous paging behaviour. See \fIvadvise\fP(2).
  1376. X.RE
  1377. X.TP 8
  1378. X\fINice\fP
  1379. XThe ``niceness'' of the process. See \fInice\fP(2).
  1380. X.TP
  1381. X\fIVirtual\fP
  1382. XThe virtual memory size of the process in kilobytes.
  1383. XThe first figure indicates the sum of the data and stack segments,
  1384. Xthe second figure that of the text segment.
  1385. X.TP
  1386. X\fIResident\fP
  1387. XThe resident memory size of the process in kilobytes, representing
  1388. Xthe real memory devoted to the process.
  1389. X.TP
  1390. X\fI%M\fP
  1391. XThe percentage of available real memory allocated to this process.
  1392. X.TP
  1393. X\fITime\fP
  1394. XThe total CPU time accumulated by this process.
  1395. X(This is the sum of the system plus user times, unless the \fB\-q\fP
  1396. Xflag is specified in which case only the user time is listed.)
  1397. X.TP
  1398. X\fIChild\fP
  1399. XThe total CPU time accumulated by the process' children.
  1400. X(This is the sum of the system plus user times, unless the \fB\-q\fP
  1401. Xflag is specified.)
  1402. X.TP
  1403. X\fI%C\fP
  1404. XThe percentage of available CPU time devoted to the process.
  1405. XThis figure is a decaying average, computed over the past second.
  1406. X.PP
  1407. XThe following fields are listed when \fIsps\fP is invoked with the
  1408. X\fB\-d\fP option \-
  1409. X.TP 8
  1410. X\fIFiles\fP
  1411. XThe number of open files for this process.
  1412. X.TP
  1413. X\fIPageFaults\fP
  1414. XThe number of major and minor page faults incurred by the process.
  1415. X.TP
  1416. X\fISwap\fP
  1417. XThe number of swaps incurred by the process.
  1418. X.TP
  1419. X\fIBlockI/O\fP
  1420. XThe number of block read or write operations performed
  1421. Xon behalf of the process.
  1422. X.TP
  1423. X\fIKbytesecs\fP
  1424. XThe integral of real memory usage over time.
  1425. XThus, if a process uses 60 kilobytes of real memory for 3 seconds,
  1426. Xthis figure is incremented by 180.
  1427. X.PP
  1428. XThe following fields are listed when \fIsps\fP is invoked with the
  1429. X\fB\-y\fP option \-
  1430. X.TP 8
  1431. X\fIDev\fP
  1432. XThe major and minor device numbers of the terminal.
  1433. X.TP
  1434. X\fIAddr\fP
  1435. XThe virtual address of the associated \fBstruct tty\fP in \fB/dev/kmem\fP.
  1436. X.TP
  1437. X\fIRawq\fP
  1438. X.br
  1439. X.ns
  1440. X.TP
  1441. X\fICanq\fP
  1442. X.br
  1443. X.ns
  1444. X.TP
  1445. X\fIOutq\fP
  1446. XThe number of characters in the terminal I/O queues.
  1447. XThese refer to the raw input queue, the canonical input queue
  1448. Xand the output queue.
  1449. X.TP
  1450. X\fIPgrp\fP
  1451. XThe process group associated with the terminal.
  1452. X.PP
  1453. XAfter listing the requested output, \fIsps\fP prints a summary line.
  1454. XThis indicates the number and total virtual memory size of all processes,
  1455. Xthe number and total virtual size of busy processes,
  1456. Xthe number and real memory size of loaded processes
  1457. Xand the number and real size of swapped processes.
  1458. X.SH DIAGNOSTICS
  1459. X\fISps\fP reports a self-explanatory message if it is given an
  1460. Xinvalid argument list.
  1461. XThe program also complains if it cannot find necessary system information.
  1462. X.PP
  1463. XAt initialisation, \fIsps\fP complains if it cannot find the addresses of
  1464. Xrequisite system structures in the kernel symbol file.
  1465. XThis is usually the case because the system is rarely configured to support
  1466. Xall known devices.
  1467. X\fISps\fP also complains if more than one user shares the same user-id
  1468. Xin the password file (\fB/etc/passwd\fP).
  1469. X.SH EXAMPLES
  1470. X\fBsps vb\fP
  1471. X.PP
  1472. X\fISps\fP describes all busy processes in a verbose manner.
  1473. X.PP
  1474. X\fBsps dtg 9 h1 co\fP
  1475. X.PP
  1476. X\fISps\fP lists processes associated with terminals \fB9\fP,
  1477. X\fBh1\fP and the \fBconsole\fP.
  1478. XThe output reflects the disc activity caused by these processes.
  1479. XThe process group of each process is also included in the output.
  1480. X.PP
  1481. X\fBsps weu robert fred \-r 2\fP
  1482. X.PP
  1483. X\fISps\fP reports processes belonging to the specified users.
  1484. XIt lists the environment as well as all the command arguments in a wide format.
  1485. XThe output is produced indefinitely, with a delay of two seconds between
  1486. Xeach listing.
  1487. X.PP
  1488. X\fBsps is /vmunix.new\fP
  1489. X.PP
  1490. X\fISps\fP is initialised. It reads its symbol information from the
  1491. Xspecified file.
  1492. X.SH FILES
  1493. X.ta 2.5i
  1494. X.nf
  1495. X\fB/dev/console\fP    Console
  1496. X\fB/dev/tty??\fP    Terminal and pty devices
  1497. X\fB/dev/kmem\fP    Kernel virtual memory
  1498. X\fB/dev/mem\fP    Physical memory
  1499. X\fB/dev/drum\fP    Paging and swap device
  1500. X\fB/etc/passwd\fP    Password file
  1501. X\fB/etc/spsinfo\fP    Information file
  1502. X\fB/vmunix\fP    Symbol file of \fB/dev/kmem\fP addresses
  1503. X\fB/etc/termcap\fP    To determine the output terminal width
  1504. X.fi
  1505. X.ta
  1506. X.SH SEE ALSO
  1507. X\fIiostat\fP(1), \fIkill\fP(1), \fIps\fP(1),
  1508. X\fIvmstat\fP(1), \fIexec\fP(2),
  1509. X\fIflock\fP(2), \fInice\fP(2), \fIpause\fP(2), \fIselect\fP(2), \fIsetuid\fP(2),
  1510. X\fIsigvec\fP(2), \fIvadvise\fP(2), \fIvfork\fP(2), \fIwait\fP(2),
  1511. X\fIpty\fP(4),\fItty\fP(4), \fIpstat\fP(8).
  1512. X.SH AUTHORS
  1513. XSeveral. In particular, J. E. Kulp and J. Robert Ward,
  1514. X\fB<robert@olsen.uucp>\fP.
  1515. X.LP
  1516. XNFS changes incorporated by Alexander Dupuy,
  1517. X\fB<dupuy@amsterdam.columbia.edu>\fP
  1518. X.LP
  1519. XSunOS 4.0 implementation by Alexander Dupuy and
  1520. XCharlie Kim \fB<cck@cunixc.cc.columbia.edu>\fP.
  1521. X.LP
  1522. XUltrix 2.\fIx\fP additions incorporated by Rob Lehman at CUUCA.
  1523. X.LP
  1524. XSunOS 4.1 additions incorporated by Sakari Jalovaara, \fB<sja@sirius.hut.fi>\fP.
  1525. X.LP
  1526. XCurrently maintained by J. Robert Ward, \fB<robert@olsen.uu.ch>\fP
  1527. X.SH BUGS
  1528. XBecause the system is continually changing, the information reported by
  1529. X\fIsps\fP is only an approximation to reality.
  1530. XIf invoked by root, \fIsps\fP renices itself to \-20 in an attempt to run as
  1531. Xfast as possible.
  1532. X.PP
  1533. X\fISps\fP recognises the sizes and addresses of internal kernel
  1534. Xtables whenever it is invoked. However, it must be recompiled
  1535. Xif major modifications are made to the kernel.
  1536. X.PP
  1537. X\fISps\fP does not list all the detailed information shown by \fIps\fP(1).
  1538. XNor are all the options supported by \fIps\fP(1) available from \fIsps\fP.
  1539. X.PP
  1540. X\fISps\fP does not understand all the possible
  1541. Xreasons why a process may be sleeping.
  1542. X.PP
  1543. XThe code of \fIsps\fP is inherently machine-dependent and non-portable.
  1544. X.PP
  1545. XThe number of options to \fIsps\fP is ridiculous.
  1546. ---END-OF-sps.l---
  1547. LEN=`wc -c < sps.l`
  1548. if [ $LEN !=  15259 ] ; then
  1549.     echo shar: File "sps.l" was $LEN, should have been 15259 bytes
  1550. fi
  1551. if [ -f 'stream.c' -a "${1}" != "-c" ] ; then
  1552.     echo shar: Won\'t overwrite existing file "stream.c"
  1553.     exit 2
  1554. fi
  1555. echo x - stream.c
  1556. sed -e 's/^X//' > stream.c << '---END-OF-stream.c---'
  1557. X# ifndef lint
  1558. Xstatic char SccsId[] =  "@(#)stream.c    1.2\t7/4/90" ;
  1559. X# endif
  1560. X
  1561. X# ifdef SUNOS40
  1562. X#  include        "sps.h"
  1563. X#  include        <h/stream.h>
  1564. X#  include        <h/vnode.h>
  1565. X#  ifdef SUNOS41
  1566. X#   include        <h/strstat.h>
  1567. X#  endif
  1568. X
  1569. Xstatic struct stdata    *pstreams ;
  1570. Xstatic struct stdata    *pstreamsNSTREAMS ;
  1571. X
  1572. Xinit_streams_tab()
  1573. X{
  1574. X    int            len ;
  1575. X    extern struct info    Info ;
  1576. X    register struct stdata    *s ;
  1577. X    struct vnode        *v ;
  1578. X    char            *getcore() ;
  1579. X
  1580. X    if ( pstreams )
  1581. X        /* reinitializing */
  1582. X        for ( s = pstreams ; s <= pstreamsNSTREAMS ; s++ )
  1583. X            if ( s->sd_vnode != 0 )
  1584. X                free( (char*)s->sd_vnode ) ;
  1585. X        free( (char*)pstreams ) ;
  1586. X#  ifdef SUNOS41
  1587. X    /*
  1588. X     * In SunOS 4.1, the stream heads are in a linked list.  A
  1589. X     * `struct strstat' contains the number of active streams; the
  1590. X     * variable `allstream' points to an apparently random
  1591. X     * position in a doubly linked `struct stdata' chain.
  1592. X     *
  1593. X     * To find all streams we'll have to scan the chain forwards
  1594. X     * AND backwards from `allstream'.  `int going_forwards' below
  1595. X     * tells which direction we are currently going.  Weird.
  1596. X     *
  1597. X     */
  1598. X
  1599. X    {
  1600. X        struct strstat        strst ;
  1601. X        int            n ;
  1602. X        long            addr ;
  1603. X        struct stdata        *this_stream ;
  1604. X        int            going_forwards = 1 ;
  1605. X    
  1606. X        if ( getkmem ((long) Info.i_strst, (char *) &strst,
  1607. X            sizeof ( struct strstat )) != sizeof ( struct strstat ))
  1608. X            return 0 ;
  1609. X        len = strst.stream.use * sizeof( struct stdata ) ;
  1610. X        pstreams = (struct stdata *)getcore (len ) ;
  1611. X        addr = (long)Info.i_allstream ;
  1612. X        this_stream = pstreams ;
  1613. X        pstreamsNSTREAMS = pstreams - 1 ;
  1614. X        for (n = 0 ; n < strst.stream.use ; n++)
  1615. X        {
  1616. X            if ( getkmem ( addr, (char *) this_stream,
  1617. X                sizeof ( struct stdata ))
  1618. X                != sizeof ( struct stdata ))
  1619. X            {
  1620. X                /*
  1621. X                 * If we are following the `sd_next' chain we'll
  1622. X                 * have to start over from the stream pointed to
  1623. X                 * by Info.i_allstream and scan `sd_prev'
  1624. X                 * backwards.
  1625. X                 */
  1626. X                if ( going_forwards && n > 0 )
  1627. X                {
  1628. X                    going_forwards = 0 ;
  1629. X                    addr = (long) pstreams[0].sd_prev ;
  1630. X                    n--;
  1631. X                    continue ;
  1632. X                }
  1633. X                if ( pstreamsNSTREAMS < pstreams )
  1634. X                    return 0 ;
  1635. X                break ;
  1636. X            }
  1637. X            addr = going_forwards ? (long) this_stream->sd_next :
  1638. X                (long) this_stream->sd_prev ;
  1639. X            this_stream++ ;
  1640. X            pstreamsNSTREAMS++ ;
  1641. X        }
  1642. X    }
  1643. X#  else SUNOS41
  1644. X    len = ((Info.i_streamsNSTREAMS - Info.i_streams) + 1)
  1645. X        * sizeof( struct stdata ) ;
  1646. X    pstreams = (struct stdata *)getcore( len ) ;
  1647. X    pstreamsNSTREAMS = pstreams + (len / sizeof( struct stdata ) ) ;
  1648. X    if ( getkmem( (long)Info.i_streams, (char *)pstreams, len ) != len )
  1649. X        return( 0 ) ;
  1650. X#  endif SUNOS41
  1651. X
  1652. X    for ( s = pstreams ; s <= pstreamsNSTREAMS ; s++ )
  1653. X        if ( s->sd_vnode != 0 )
  1654. X        {
  1655. X            if ( ( v = (struct vnode*)getcore( sizeof( *v ) ) )
  1656. X            && getkmem( (long)s->sd_vnode, (char*)v, sizeof( *v ) )
  1657. X            == sizeof( *v ) )
  1658. X            {
  1659. X                s->sd_vnode = v ;
  1660. X                continue ;
  1661. X            }
  1662. X
  1663. X            s->sd_vnode = 0 ;
  1664. X        }
  1665. X    return( 1 ) ;
  1666. X}
  1667. X
  1668. X
  1669. X#  ifdef SUNOS41
  1670. Xstruct sess *find_session ( addr )
  1671. X
  1672. Xstruct sess            *addr ;
  1673. X
  1674. X{
  1675. X    /*
  1676. X     * SunOS 4.1 seems to store controlling tty's in a "struct
  1677. X     * sess" which is accessible as p->p_sessp.  Another layer
  1678. X     * of indirection to wade through...
  1679. X     *
  1680. X     * To make this a tiny bit faster, I'll store sessions in a
  1681. X     * linked list as I read them in with getkmem; subsequent
  1682. X     * calls to find_session() check the cache.
  1683. X     */
  1684. X
  1685. X    struct sps_sess {
  1686. X        struct sess        sess ;
  1687. X        struct sess        *addr ;
  1688. X        struct sps_sess        *next ;
  1689. X    };
  1690. X
  1691. X    static struct sps_sess        *sessions ; /* Cache of known sessions*/
  1692. X    register struct sps_sess    *s ;
  1693. X
  1694. X    /* Try to find the session in the cache */
  1695. X    for ( s = sessions ; s ; s = s->next )
  1696. X        if ( s->addr == addr )
  1697. X            return &s->sess ;
  1698. X    /* Not found; get it from kmem and put it in the cache */
  1699. X    s = (struct sps_sess *)getcore( sizeof ( struct sps_sess ) ) ;
  1700. X    if ( getkmem ((long) addr, (char *) &s->sess,
  1701. X            sizeof ( struct sess )) != sizeof ( struct sess ) )
  1702. X        return 0 ;
  1703. X    s->addr = addr ;
  1704. X    s->next = sessions ;
  1705. X    sessions = s ;
  1706. X    return &s->sess ;
  1707. X}
  1708. X#  endif SUNOS41
  1709. X
  1710. Xstruct stdata *getstdata ( st, dev )
  1711. X
  1712. Xstruct streamtab                *st ;
  1713. Xdev_t                            dev ;
  1714. X
  1715. X{
  1716. X    register struct stdata  *s ;
  1717. X
  1718. X    for ( s = pstreams ; s <= pstreamsNSTREAMS ; s++ )
  1719. X        if ( s->sd_strtab == st && s->sd_vnode
  1720. X        && s->sd_vnode->v_rdev == dev )
  1721. X            return( s ) ;
  1722. X    return( 0 ) ;
  1723. X}
  1724. X
  1725. X/* 1 if `w' is in the address range defined by `a1' and `a2' ... */
  1726. X# define        INRANGE( w, a1, a2 ) \
  1727. X            ( (caddr_t)(a1) <= (w) && (w) < (caddr_t)(a2) )
  1728. X
  1729. Xchar *gettty ( lp, w )
  1730. X
  1731. Xregister struct ttyline         *lp ;
  1732. Xcaddr_t                         w ;
  1733. X
  1734. X{
  1735. X    struct stdata           *s ;
  1736. X    struct queue            *q ;
  1737. X    struct queue            qq[2] ;
  1738. X    char                    *cp = 0 ;
  1739. X
  1740. X    if ( ( s = lp->l_stdata ) == 0 )
  1741. X        return( 0 ) ;
  1742. X
  1743. X    q = s->sd_wrq ;        /* get write queue (only queue_t in stdata) */
  1744. X    do
  1745. X    {
  1746. X        if ( INRANGE( w, RD( q ), q ) )
  1747. X        {            /* check read queue */
  1748. X            cp = "rtty??" ;
  1749. X            break ;
  1750. X        }
  1751. X        if ( INRANGE( w, q, WR ( q ) ) )
  1752. X        {            /* check write queue */
  1753. X            cp = "wtty??" ;
  1754. X            break ;
  1755. X        }
  1756. X        /* check queue private data structures - useful??? */
  1757. X        if ( getkmem( (long)RD( q ), (char*)qq, sizeof( qq ) )
  1758. X        != sizeof( qq ) )
  1759. X            break ;
  1760. X        if ( INRANGE( w, qq[0].q_ptr, qq[0].q_ptr + 1 ) )
  1761. X        {
  1762. X            cp = "r?ty??" ;
  1763. X        }
  1764. X        if ( INRANGE( w, qq[1].q_ptr, qq[1].q_ptr + 1 ) )
  1765. X        {
  1766. X            cp = "w?ty??" ;
  1767. X        }
  1768. X        q = qq[1].q_next ;
  1769. X    }
  1770. X    while ( q ) ;
  1771. X    if ( cp )
  1772. X    {
  1773. X        cp[4] = lp->l_name[0] ;
  1774. X        cp[5] = lp->l_name[1] ;
  1775. X        return( cp ) ;
  1776. X    }
  1777. X    return( 0 ) ;            /* chain down list? */
  1778. X}
  1779. X# endif SUNOS40
  1780. X
  1781. ---END-OF-stream.c---
  1782. LEN=`wc -c < stream.c`
  1783. if [ $LEN !=  5425 ] ; then
  1784.     echo shar: File "stream.c" was $LEN, should have been 5425 bytes
  1785. fi
  1786. if [ -f 'termwidth.c' -a "${1}" != "-c" ] ; then
  1787.     echo shar: Won\'t overwrite existing file "termwidth.c"
  1788.     exit 2
  1789. fi
  1790. echo x - termwidth.c
  1791. sed -e 's/^X//' > termwidth.c << '---END-OF-termwidth.c---'
  1792. X# ifndef lint
  1793. Xstatic char SccsId[] =  "@(#)termwidth.c    1.3\t8/6/90" ;
  1794. X# endif
  1795. X
  1796. X# include    <sys/ioctl.h>
  1797. X
  1798. X/*
  1799. X** TERMWIDTH - Sets the external variable `Termwidth' to the # of columns
  1800. X** on the terminal.
  1801. X*/
  1802. Xtermwidth ()
  1803. X{
  1804. X    register char           *termtype ;
  1805. X    register int            twidth ;
  1806. X# ifdef TIOCGWINSZ
  1807. X    struct winsize        w ;
  1808. X# else
  1809. X# ifdef TIOCGSIZE
  1810. X    struct ttysize          w ;
  1811. X# endif
  1812. X# endif
  1813. X    char                    buf[ 1025 ] ;
  1814. X    extern unsigned         Termwidth ;
  1815. X    char                    *getenv() ;
  1816. X
  1817. X# ifdef TIOCGWINSZ
  1818. X    w.ws_col = 0 ;
  1819. X    if ( !ioctl( 0, TIOCGWINSZ, &w ) && w.ws_col )
  1820. X    {
  1821. X        Termwidth = w.ws_col ;
  1822. X        return ;
  1823. X    }
  1824. X# else
  1825. X# ifdef TIOCGSIZE
  1826. X    w.ts_cols = 0 ;
  1827. X    if ( !ioctl( 0, TIOCGSIZE, &w ) && w.ts_cols )
  1828. X    {
  1829. X        Termwidth = w.ts_cols ;
  1830. X        return ;
  1831. X    }
  1832. X# endif
  1833. X# endif
  1834. X    Termwidth = 80 ;
  1835. X    if ( !(termtype = getenv( "TERM" )) )
  1836. X        return ;
  1837. X    if ( tgetent( buf, termtype ) != 1 )
  1838. X        return ;
  1839. X    twidth = tgetnum( "co" ) ;
  1840. X    if ( twidth > 40 )
  1841. X        Termwidth = twidth ;
  1842. X}
  1843. ---END-OF-termwidth.c---
  1844. LEN=`wc -c < termwidth.c`
  1845. if [ $LEN !=  978 ] ; then
  1846.     echo shar: File "termwidth.c" was $LEN, should have been 978 bytes
  1847. fi
  1848. if [ -f 'ttystatus.c' -a "${1}" != "-c" ] ; then
  1849.     echo shar: Won\'t overwrite existing file "ttystatus.c"
  1850.     exit 2
  1851. fi
  1852. echo x - ttystatus.c
  1853. sed -e 's/^X//' > ttystatus.c << '---END-OF-ttystatus.c---'
  1854. X# ifndef lint
  1855. Xstatic char SccsId[] =  "@(#)ttystatus.c    1.1\t10/1/88" ;
  1856. X# endif
  1857. X
  1858. X# include       "sps.h"
  1859. X# include       "flags.h"
  1860. X# include       <stdio.h>
  1861. X# include       <h/ioctl.h>
  1862. X# ifdef SUNOS40
  1863. X# include       <h/stream.h>
  1864. X# else
  1865. X# include       <h/tty.h>
  1866. X# endif
  1867. X# ifdef CHAOS
  1868. X# include       <chunix/chsys.h>
  1869. X# include       <chaos/chaos.h>
  1870. X# endif
  1871. X
  1872. X/*
  1873. X** TTYSTATUS - Reads the kernel memory for tty structures of active processes.
  1874. X** The addresses of the associated struct ttys of /dev/kmem are kept in the
  1875. X** info structure. Here we use those addresses to access the structures.
  1876. X** Actually, we are mostly interested just in the process group of each tty.
  1877. X*/
  1878. Xttystatus ()
  1879. X{
  1880. X    register struct ttyline *lp ;
  1881. X# ifdef SUNOS40
  1882. X    struct stdata           *stdata ;
  1883. X    extern struct stdata    *getstdata() ;
  1884. X# else
  1885. X    struct tty              tty ;
  1886. X# endif
  1887. X    extern struct flags     Flg ;
  1888. X    extern struct info      Info ;
  1889. X# ifndef KVM
  1890. X    extern int              Flkmem ;
  1891. X# endif
  1892. X
  1893. X# ifdef SUNOS40
  1894. X    if ( !init_streams_tab() )
  1895. X        fprintf( stderr, "can't read streams table\n" ) ;
  1896. X# endif
  1897. X
  1898. X    if ( Flg.flg_y )
  1899. X# ifdef SUNOS40
  1900. X        printf( "Ty   Dev       Addr  Pgrp\n" ) ;
  1901. X# else
  1902. X        printf( "Ty   Dev       Addr Rawq Canq Outq  Pgrp\n" ) ;
  1903. X# endif
  1904. X    lp = Info.i_ttyline ;
  1905. X# ifdef CHAOS
  1906. X    while ( lp->l_name[0] && lp->l_name[0] != 'C' )
  1907. X# else
  1908. X    while ( lp->l_name[0] )
  1909. X# endif
  1910. X    {
  1911. X# ifdef SUNOS40 
  1912. X        if ( stdata = getstdata ( lp->l_addr, lp->l_dev ) )
  1913. X        {
  1914. X            lp->l_stdata = stdata ;
  1915. X            lp->l_pgrp = stdata->sd_pgrp ;
  1916. X            prstr( lp, stdata ) ;
  1917. X        }
  1918. X        else
  1919. X            lp->l_pgrp = 0 ;
  1920. X        lp++ ;
  1921. X# else
  1922. X        if ( getkmem( (long)lp->l_addr, (char*)&tty, sizeof( tty ) )
  1923. X        != sizeof( struct tty ) )
  1924. X        {
  1925. X            fprintf( stderr,
  1926. X                "sps - Can't read struct tty for tty%.2s\n",
  1927. X                lp->l_name ) ;
  1928. X            lp->l_pgrp = 0 ;
  1929. X            lp++ ;
  1930. X            continue ;
  1931. X        }
  1932. X        lp->l_pgrp = tty.t_pgrp ;
  1933. X        prtty( lp, &tty ) ;
  1934. X        lp++ ;
  1935. X# endif
  1936. X    }
  1937. X# ifdef CHAOS
  1938. X    chaosttys( lp ) ;               
  1939. X# endif
  1940. X}
  1941. X
  1942. X# ifdef SUNOS40
  1943. X
  1944. X/* PRSTR - Print out the stdata structure */
  1945. Xprstr ( lp, stdata )
  1946. X
  1947. Xregister struct ttyline         *lp ;
  1948. Xregister struct stdata          *stdata ;
  1949. X
  1950. X{
  1951. X    extern struct flags     Flg ;
  1952. X
  1953. X    if ( !Flg.flg_y )
  1954. X        return ;
  1955. X    printf( "%-2.2s %2d,%2d 0x%08x %5d\n",
  1956. X        lp->l_name,
  1957. X        major( lp->l_dev ),
  1958. X        minor( lp->l_dev ),
  1959. X        lp->l_addr,
  1960. X        stdata->sd_pgrp ) ;
  1961. X}
  1962. X
  1963. X# else
  1964. X
  1965. X/* PRTTY - Print out the tty structure */
  1966. Xprtty ( lp, tty )
  1967. X
  1968. Xregister struct ttyline         *lp ;
  1969. Xregister struct tty             *tty ;
  1970. X
  1971. X{
  1972. X    extern struct flags     Flg ;
  1973. X
  1974. X    if ( !Flg.flg_y )
  1975. X        return ;
  1976. X    printf( "%-2.2s %2d,%2d 0x%08x %4d %4d %4d %5d\n",
  1977. X        lp->l_name,
  1978. X        major( lp->l_dev ),
  1979. X        minor( lp->l_dev ),
  1980. X        lp->l_addr,
  1981. X        tty->t_rawq.c_cc,
  1982. X        tty->t_canq.c_cc,
  1983. X        tty->t_outq.c_cc,
  1984. X        tty->t_pgrp ) ;
  1985. X}
  1986. X
  1987. X# endif
  1988. X
  1989. X# ifdef CHAOS
  1990. X
  1991. X/* CHAOSTTYS - Finds ttys attached to the Chaos net */
  1992. Xchaosttys ( lp )
  1993. X
  1994. Xregister struct ttyline         *lp ;
  1995. X
  1996. X{
  1997. X    register struct connection      **cnp ;
  1998. X    register int                    i ;
  1999. X    struct tty                      tty ;
  2000. X    struct connection               *conntab[CHNCONNS] ;
  2001. X    struct connection               conn ;
  2002. X    extern struct info              Info ;
  2003. X    extern int                      Flkmem ;
  2004. X
  2005. X    (void)getkmem( (long)Info.i_Chconntab, (char*)conntab,
  2006. X        sizeof( conntab ) ) ;
  2007. X    for ( i = 0, cnp = conntab ; cnp < &conntab[CHNCONNS] ; i++, cnp++ )
  2008. X    {
  2009. X        if ( !*cnp )
  2010. X            continue ;
  2011. X        (void)getkmem( (long)*cnp, (char*)&conn, sizeof( conn ) ) ;
  2012. X        if ( !(conn.cn_flags & CHTTY) )
  2013. X            continue ;
  2014. X        (void)getkmem( (long)conn.cn_ttyp, (char*)&tty, sizeof( tty ) ) ;
  2015. X        if ( lp >= &Info.i_ttyline[MAXTTYS] )
  2016. X            prexit( "sps - Too many chaos ttys\n" ) ;
  2017. X        lp->l_addr = conn.cn_ttyp ;
  2018. X        lp->l_pgrp = tty.t_pgrp ;
  2019. X        lp->l_dev = tty.t_dev ;
  2020. X        lp->l_name[0] = 'C' ;
  2021. X        lp->l_name[1] = i < 10 ? '0'+i : i-10 <= 'z'-'a' ? i-10+'a' :
  2022. X                i-10-('z'-'a')+'A' ;
  2023. X        prtty( lp, &tty ) ;
  2024. X        lp++ ;
  2025. X    }
  2026. X}
  2027. X
  2028. X# endif
  2029. ---END-OF-ttystatus.c---
  2030. LEN=`wc -c < ttystatus.c`
  2031. if [ $LEN !=  3826 ] ; then
  2032.     echo shar: File "ttystatus.c" was $LEN, should have been 3826 bytes
  2033. fi
  2034. if [ -f 'vmstat.c' -a "${1}" != "-c" ] ; then
  2035.     echo shar: Won\'t overwrite existing file "vmstat.c"
  2036.     exit 2
  2037. fi
  2038. echo x - vmstat.c
  2039. sed -e 's/^X//' > vmstat.c << '---END-OF-vmstat.c---'
  2040. X# ifndef lint
  2041. Xstatic char SccsId[] =  "@(#)vmstat.c    1.1\t10/1/88" ;
  2042. X# endif
  2043. X
  2044. X# ifdef SUNOS40
  2045. X# ifndef OLDSTATS
  2046. X# include "sps.h"
  2047. X# include <h/mman.h>
  2048. X# include <vm/hat.h>
  2049. X# include <vm/as.h>
  2050. X# include <vm/seg.h>
  2051. X# include <vm/seg_vn.h>
  2052. X
  2053. Xseg_count ( p )
  2054. X
  2055. Xstruct process                  *p ;
  2056. X
  2057. X{
  2058. X    extern struct info      Info ;
  2059. X    struct as               as ;        /* address space */
  2060. X    struct seg              seg ;        /* segment in addr space */
  2061. X    struct segvn_data       vn_data ;
  2062. X    unsigned                private = 0 ;
  2063. X    unsigned                shared = 0 ;
  2064. X
  2065. X    p->pr_private = 0 ;
  2066. X    p->pr_shared = 0 ;
  2067. X
  2068. X    if ( getkmem( (long)p->pr_p.p_as, &as, sizeof( as ) ) != sizeof( as ) )
  2069. X        return( -1 ) ;
  2070. X    seg.s_next = as.a_segs ;    /* setup for loop */
  2071. X    do
  2072. X    {
  2073. X        if ( ( getkmem( seg.s_next, &seg, sizeof( seg ) ) )
  2074. X        != sizeof( seg ) )
  2075. X            break ;
  2076. X        if ( seg.s_as != p->pr_p.p_as )
  2077. X            continue ;    /* invalid segment */
  2078. X        if ( seg.s_ops != Info.i_segvn_ops )
  2079. X        {            /* mapped device is "shared" */
  2080. X            shared += seg.s_size ;
  2081. X            continue ;
  2082. X        }
  2083. X        if ( getkmem( (long)seg.s_data, &vn_data, sizeof( vn_data ) )
  2084. X        != sizeof( vn_data ) )
  2085. X            continue ;
  2086. X        /*
  2087. X         * If a segment has an anonymous mapping, it is in the swap
  2088. X         * area.  If it is also MAP_PRIVATE, we consider it "private"
  2089. X         * (even though it may be shared between parent and child after
  2090. X         * a fork() call).  Segments without an anonymous mapping are
  2091. X         * considered to be "shared".  [Should we worry about swap
  2092. X         * space reserved for copy-on-write shared segments?]
  2093. X         */
  2094. X
  2095. X        if ( vn_data.amp && (vn_data.type & MAP_TYPE) == MAP_PRIVATE )
  2096. X            private += seg.s_size ;
  2097. X        else
  2098. X            shared += seg.s_size ;
  2099. X    }
  2100. X    while ( seg.s_next != as.a_segs ) ;
  2101. X
  2102. X# define BYTETOPAGE(x) (((x)+(PAGESIZE-1))>>PGSHIFT)
  2103. X
  2104. X    p->pr_private = BYTETOPAGE( private ) ;
  2105. X    p->pr_shared = BYTETOPAGE( shared ) ;
  2106. X    p->pr_p.p_rssize = as.a_rss ;    /* update count of resident pages */
  2107. X    return( 0 ) ;
  2108. X}
  2109. X# endif
  2110. X# endif
  2111. ---END-OF-vmstat.c---
  2112. LEN=`wc -c < vmstat.c`
  2113. if [ $LEN !=  1902 ] ; then
  2114.     echo shar: File "vmstat.c" was $LEN, should have been 1902 bytes
  2115. fi
  2116. if [ -f 'waitingfor.c' -a "${1}" != "-c" ] ; then
  2117.     echo shar: Won\'t overwrite existing file "waitingfor.c"
  2118.     exit 2
  2119. fi
  2120. echo x - waitingfor.c
  2121. sed -e 's/^X//' > waitingfor.c << '---END-OF-waitingfor.c---'
  2122. X# ifndef lint
  2123. Xstatic char SccsId[] =  "@(#)waitingfor.c    1.5\t8/6/90" ;
  2124. X# endif
  2125. X
  2126. X# include        "sps.h"
  2127. X# ifndef SUNOS40
  2128. X# include        <h/text.h>
  2129. X# endif SUNOS40
  2130. X
  2131. X# ifdef NFS
  2132. X#  ifdef DEC3100
  2133. X#   include        <h/gnode.h>
  2134. X#   include        <h/inode.h>
  2135. X#  else DEC3100
  2136. X#   include        <h/vnode.h>
  2137. X#   include        <ufs/inode.h>
  2138. X# endif DEC3100
  2139. X# else
  2140. X#  include        <h/inode.h>
  2141. X# endif NFS
  2142. X
  2143. X# include        <h/ioctl.h>
  2144. X# ifdef SUNOS40
  2145. X#  include        <h/stream.h>
  2146. X#  include        <h/tty.h>
  2147. X#  include        <h/ptyvar.h>
  2148. X# else SUNOS40
  2149. X#  include        <h/tty.h>
  2150. X# endif SUNOS40
  2151. X
  2152. X# include        <h/buf.h>
  2153. X# ifdef BSD42
  2154. X#  ifdef NFS
  2155. X#   ifndef NOQUOTA
  2156. X#    ifdef DEC3100
  2157. X#     include        <h/quota.h>
  2158. X#    else
  2159. X#     include        <ufs/quota.h>
  2160. X#    endif DEC3100
  2161. X#   endif NOQUOTA
  2162. X#  else NFS
  2163. X#   include        <h/quota.h>
  2164. X#  endif NFS
  2165. X# include        <h/mbuf.h>
  2166. X# include        <h/socket.h>
  2167. X# include        <h/socketvar.h>
  2168. X# endif BSD42
  2169. X
  2170. X/* 1 if `w' is in the address range defined by `a1' and `a2' ... */
  2171. X# define        INRANGE( w, a1, a2 ) \
  2172. X            ( (caddr_t)(a1) <= (w) && (w) < (caddr_t)(a2) )
  2173. X
  2174. X/* NFS changes incorporated by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
  2175. X
  2176. X/* WAITINGFOR - Determine what a process is waiting for and describe it. */
  2177. Xchar    *waitingfor ( p )
  2178. X
  2179. Xstruct process                  *p ;
  2180. X
  2181. X{
  2182. X    register caddr_t        w ;
  2183. X    register struct ttyline *lp ;
  2184. X    register struct symbol  *s ;
  2185. X    register char           *cp ;
  2186. X# ifdef BSD42
  2187. X    struct socket           sc ;
  2188. X# endif
  2189. X    int            rc ;
  2190. X    static char             wbuf[ 8 ] ;
  2191. X    extern struct info      Info ;
  2192. X    extern struct symbol    Symbollist[] ;
  2193. X    char                    *sprintf() ;
  2194. X# ifdef SUNOS40
  2195. X    char                    *gettty() ;
  2196. X# endif
  2197. X
  2198. X    w = p->pr_p.p_wchan ;
  2199. X    if ( !w )
  2200. X        return ( "null" ) ;
  2201. X    /* Waiting for a child process, alternatively in a vfork() ? */
  2202. X    if ( INRANGE( w, Info.i_proc0, &Info.i_proc0[ Info.i_nproc ] ) )
  2203. X        return ( p->pr_p.p_flag & SNOVM ? "vfork" : "child" ) ;
  2204. X# ifndef SUNOS40
  2205. X    /* Waiting for a page to be brought in ? */
  2206. X    if ( INRANGE( w, Info.i_swbuf0, &Info.i_swbuf0[ Info.i_nswbuf ] ) )
  2207. X        return ( "swap" ) ;
  2208. X    /* Waiting for discio through a block device to complete ? */
  2209. X    if ( INRANGE( w, Info.i_buf0, &Info.i_buf0[ Info.i_nbuf ] ) )
  2210. X        /* SHOULD ACTUALLY READ AS "blkio" BUT "discio" IS WHAT
  2211. X           IS GENERALLY MEANT HERE. */
  2212. X        return ( "discio" ) ;
  2213. X    /* Waiting for a text page to be brought in ? */
  2214. X    if ( INRANGE( w, Info.i_text0, &Info.i_text0[ Info.i_ntext ] ) )
  2215. X        return ( "swtext" ) ;
  2216. X# endif SUNOS40
  2217. X
  2218. X# ifdef BSD42
  2219. X#  ifndef NOQUOTA
  2220. X    /* Waiting for an event associated with the quota system ? */
  2221. X    if ( INRANGE( w, Info.i_quota0, &Info.i_quota0[ Info.i_nquota ] ) )
  2222. X        return ( "quota" ) ;
  2223. X#  endif NOQUOTA
  2224. X# endif BSD42
  2225. X
  2226. X# ifndef SUNOS41
  2227. X         /* Sorry, I don't know how to do this...
  2228. X          * I kinda think that SunOS 4.1 allocates inode
  2229. X          * buffer entries dynamically.  Maybe it could be
  2230. X          * possible to read in all "struct file"s and
  2231. X          * compare each file.f_data to the wait channel.    ++sja
  2232. X          */
  2233. X    /* Waiting for an inode ? */
  2234. X    if ( INRANGE( w, Info.i_inode0, &Info.i_inode0[ Info.i_ninode ] ) )
  2235. X#  ifdef ULTRIX20
  2236. X        switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct gnode ))
  2237. X#  else
  2238. X        switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct inode ))
  2239. X#  endif ULTRIX20
  2240. X        {
  2241. X#  ifdef BSD42
  2242. X#   ifdef NFS
  2243. X            case (int)&((struct inode*)0)->i_vnode.v_exlockc :
  2244. X                /* Exclusive lock on this inode */
  2245. X                return ( "exlock" ) ;
  2246. X            case (int)&((struct inode*)0)->i_vnode.v_shlockc :
  2247. X                /* Shared lock on this inode */
  2248. X                return ( "shlock" ) ;
  2249. X#   else NFS
  2250. X#    ifdef ULTRIX20
  2251. X#     ifndef DEC3100
  2252. X            /* Compile this code with gcc if you want to run it
  2253. X               properly.  The DEC compiler can't handle this. */
  2254. X            case (int)&((struct gnode*)0)->g_exlockc :
  2255. X                /* Exclusive lock on this inode */
  2256. X                return ( "exlock" ) ;
  2257. X            case (int)&((struct gnode*)0)->g_shlockc :
  2258. X                /* Shared lock on this inode */
  2259. X                return ( "shlock" ) ;
  2260. X            case (int)&((struct gnode*)0)->g_frcnt :
  2261. X                /* Open fifo with no readers */
  2262. X                return ( "wfifo" ) ;
  2263. X            case (int)&((struct gnode*)0)->g_fwcnt :
  2264. X                /* Open fifo with no writers */
  2265. X                return ( "rfifo" ) ;
  2266. X#     endif DEC3100
  2267. X#    else ULTRIX20
  2268. X            case (int)&((struct inode*)0)->i_exlockc :
  2269. X                /* Exclusive lock on this inode */
  2270. X                return ( "exlock" ) ;
  2271. X            case (int)&((struct inode*)0)->i_shlockc :
  2272. X                /* Shared lock on this inode */
  2273. X                return ( "shlock" ) ;
  2274. X#    endif ULTRIX20
  2275. X#   endif NFS
  2276. X#  else BSD42 
  2277. X            case 1 :
  2278. X                return ( "wpipe" ) ;
  2279. X            case 2 :
  2280. X                return ( "rpipe" ) ;
  2281. X            case (int)&((struct inode*)0)->i_un.i_group.g_datq :
  2282. X                return ( "rmux" ) ;
  2283. X#  endif BSD42
  2284. X            default :
  2285. X                /* Inode probably locked */
  2286. X                return ( "inode" ) ;
  2287. X        }
  2288. X# endif SUNOS41
  2289. X
  2290. X# if defined(BSD42) && (defined(SUNOS40) || defined(NMBCLUSTERS))
  2291. X    /* Waiting for a structure inside an mbuf ? If so, try to find why */
  2292. X#  ifdef SUNOS40
  2293. X    if ( INRANGE( w, Info.i_mbutl,
  2294. X    &Info.i_mbutl[ MBPOOLBYTES / sizeof( struct mbuf ) ] ) )
  2295. X#  else
  2296. X    if ( INRANGE( w, Info.i_mbutl,
  2297. X    &Info.i_mbutl[ NMBCLUSTERS * CLBYTES / sizeof( struct mbuf ) ] ) )
  2298. X#  endif SUNOS40
  2299. X        switch ( ((int)w - (int)Info.i_mbutl) % sizeof( struct mbuf )
  2300. X            - (int)&((struct mbuf*)0)->m_dat[0] )
  2301. X        {
  2302. X            case (int)&((struct socket*)0)->so_timeo :
  2303. X                /* Socket timeout event - Guess why */
  2304. X                rc = getsocket( (struct socket*)(w
  2305. X                    - (int)&((struct socket*)0)->so_timeo),
  2306. X                        &sc ) ;
  2307. X                return ( rc && (sc.so_state & SS_ISCONNECTING)
  2308. X                    ? "connct" 
  2309. X                    : rc && ((sc.so_options & SO_ACCEPTCONN)
  2310. X                      && !sc.so_qlen)
  2311. X                    ? "accept" : "socket" ) ;
  2312. X            case (int)&((struct socket*)0)->so_rcv.sb_cc :
  2313. X                /* Read from an empty socket. Here we actually
  2314. X                   attempt to determine whether the socket
  2315. X                   structure in question really does refer to
  2316. X                   a socket, or whether it is in fact a pipe
  2317. X                   in disguise. */
  2318. X                return ( getsocket( (struct socket*)(w
  2319. X                    - (int)&((struct socket*)0)->so_rcv.sb_cc),
  2320. X                        &sc )
  2321. X                    && sc.so_type == SOCK_STREAM
  2322. X#  ifdef BSD43
  2323. X                    && ((sc.so_state
  2324. X                        & (SS_ISCONNECTED|SS_CANTSENDMORE))
  2325. X                        == (SS_ISCONNECTED|SS_CANTSENDMORE))
  2326. X#  else
  2327. X                    && !sc.so_rcv.sb_hiwat
  2328. X                    && !sc.so_rcv.sb_mbmax
  2329. X                    && (sc.so_state
  2330. X                        & (SS_ISCONNECTED|SS_CANTRCVMORE))
  2331. X#  endif BSD43
  2332. X                    ? "rpipe" : "rsockt" ) ;
  2333. X            case (int)&((struct socket*)0)->so_snd.sb_cc :
  2334. X                /* Write to a full socket. Again, we try
  2335. X                   to determine whether or not this is a
  2336. X                   real socket or a pipe. */
  2337. X                return ( getsocket( (struct socket*)(w
  2338. X                    - (int)&((struct socket*)0)->so_snd.sb_cc),
  2339. X                        &sc )
  2340. X#  ifdef BSD43
  2341. X                    && sc.so_type == SOCK_STREAM
  2342. X                    && ((sc.so_state
  2343. X                        & (SS_ISCONNECTED|SS_CANTRCVMORE))
  2344. X                        == (SS_ISCONNECTED|SS_CANTRCVMORE))
  2345. X#  else
  2346. X                    && sc.so_rcv.sb_hiwat == 2048
  2347. X                    && sc.so_rcv.sb_mbmax == 4096
  2348. X                    && (sc.so_state
  2349. X                        & (SS_ISCONNECTED|SS_CANTSENDMORE))
  2350. X#  endif BSD43
  2351. X                    ? "wpipe" : "wsockt" ) ;
  2352. X            default :
  2353. X                /* Other mbuf event */
  2354. X                return ( "mbuf" ) ;
  2355. X        }
  2356. X# endif BSD42
  2357. X
  2358. X# ifdef SUNOS41
  2359. X    if  ( w == (caddr_t)p->pr_p.p_uarea )
  2360. X        return ( "pause" ) ;
  2361. X# endif SUNOS41
  2362. X    /* Look in the symbol table for known wait addresses. */
  2363. X    for ( s = Symbollist ; s->s_kname ; s++ )
  2364. X        if ( s->s_wait && w == *s->s_info )
  2365. X            return ( s->s_wait ) ;
  2366. X
  2367. X# ifdef SUNOS40
  2368. X    /* Have to check for ptys in a funny sort of way */
  2369. X    if ( INRANGE( w, Info.i_ptybase, &Info.i_ptybase[ Info.i_npty ] ) )
  2370. X    {
  2371. X        switch ( ((int)w - (int)Info.i_ptybase) % sizeof( struct pty ) )
  2372. X        {
  2373. X            case (int)&((struct pty*)0)->pt_flags :
  2374. X                cp = "opty??" ;
  2375. X                break ;
  2376. X            case (int)&((struct pty*)0)->pt_ttycommon.t_writeq :
  2377. X                cp = "spty??" ;
  2378. X                break ;
  2379. X            default :
  2380. X                cp = "?pty??" ;
  2381. X        }
  2382. X        /* by the conventional naming, anyhow */
  2383. X        cp[4] = 'p' + (((int)w - (int)Info.i_ptybase)
  2384. X            / sizeof( struct pty )) / 16 ;
  2385. X        if ( ( cp[5] = '0' + (((int) w - (int)Info.i_ptybase)
  2386. X            / sizeof( struct pty )) % 16 ) > '9' )
  2387. X            cp[5] += 'a' - '9' - 1 ;
  2388. X        return( cp ) ;
  2389. X    }
  2390. X    /* Check for ttys last, since there may be a lot of them. */
  2391. X    if ( p->pr_tty != 0 )
  2392. X        if ( cp = gettty( p->pr_tty, w ) )
  2393. X            return( cp ) ;
  2394. X    for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
  2395. X        if ( cp = gettty( lp, w ) )
  2396. X            return( cp ) ;
  2397. X# else SUNOS40
  2398. X    /* Waiting for tty I/O ? If so, find which tty it is */
  2399. X    for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
  2400. X        if ( INRANGE( w, &lp->l_addr[0], &lp->l_addr[1] ) )
  2401. X        {
  2402. X#  ifdef DEC3100
  2403. X            /* Cretinous DEC compiler can't handle case
  2404. X               constructs like the following ... */
  2405. X            cp = "?tty??" ;
  2406. X#  else DEC3100
  2407. X            switch ( (int)w - (int)lp->l_addr )
  2408. X            {
  2409. X                case (int)&((struct tty*)0)->t_rawq :
  2410. X                    /* Read from a tty or slave pty */
  2411. X                    cp = "rtty??" ;
  2412. X                    break ;
  2413. X                case (int)&((struct tty*)0)->t_outq :
  2414. X                    /* Write to a tty or slave pty */
  2415. X                    cp = "wtty??" ;
  2416. X                    break ;
  2417. X                case (int)&((struct tty*)0)->t_canq :
  2418. X                    /* Waiting for icon to be opened */
  2419. X                    cp = "itty??" ;
  2420. X                    break ;
  2421. X                case (int)&((struct tty*)0)->t_state :
  2422. X                    /* Tty not open */
  2423. X                    cp = "otty??" ;
  2424. X                    break ;
  2425. X                case (int)&((struct tty*)0)->t_outq.c_cf :
  2426. X                    /* Read from a controller pty */
  2427. X                    cp = "rpty??" ;
  2428. X                    break ;
  2429. X                case (int)&((struct tty*)0)->t_rawq.c_cf :
  2430. X                    /* Write to a controller pty */
  2431. X                    cp = "wpty??" ;
  2432. X                    break ;
  2433. X                default :
  2434. X                    cp = "?tty??" ;
  2435. X                    break ;
  2436. X            }
  2437. X#  endif DEC3100
  2438. X            cp[4] = lp->l_name[0] ;
  2439. X            cp[5] = lp->l_name[1] ;
  2440. X            return ( cp ) ;
  2441. X        }
  2442. X# endif SUNOS40
  2443. X
  2444. X    /* No reason for the wait state has been found.
  2445. X       Return the wait channel as a hexadecimal address. */
  2446. X# ifdef SUN
  2447. X    (void)sprintf( wbuf, "x%05x", w - KERNELBASE ) ;
  2448. X# else
  2449. X    (void)sprintf( wbuf, "x%05x", w - 0x80000000 ) ;
  2450. X# endif
  2451. X    return ( wbuf ) ;
  2452. X}
  2453. X
  2454. X
  2455. X# ifdef BSD42
  2456. X/*
  2457. X** GETSOCKET - Reads a `struct socket' from the kernel virtual memory address
  2458. X** identified by `ks' into the buffer `s'.
  2459. X*/
  2460. Xgetsocket ( ks, s )
  2461. X
  2462. Xstruct socket                   *ks ;
  2463. Xstruct socket                   *s ;
  2464. X
  2465. X{
  2466. X    return ( getkmem( (long)ks, (char*)s, sizeof( struct socket ) )
  2467. X        == sizeof( struct socket ) ) ;
  2468. X}
  2469. X# endif BSD42
  2470. ---END-OF-waitingfor.c---
  2471. LEN=`wc -c < waitingfor.c`
  2472. if [ $LEN !=  9904 ] ; then
  2473.     echo shar: File "waitingfor.c" was $LEN, should have been 9904 bytes
  2474. fi
  2475. exit 0
  2476.