home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / 3b1 / volume02 / lavgtls / part01 < prev    next >
Encoding:
Internet Message Format  |  1992-06-22  |  15.5 KB

  1. Path: comp-sources-3b1
  2. From: dburr@sbphy.physics.ucsb.edu (Donald Burr)
  3. Subject:  v02i003:  Load average routines and uptime command, Part01/01
  4. Newsgroups: comp.sources.3b1
  5. Approved: dave@galaxia.newport.ri.us
  6. X-Checksum-Snefru: b7c4edd4 5ddf7da8 e861cb07 009426e0
  7.  
  8. Submitted-by: dburr@sbphy.physics.ucsb.edu (Donald Burr)
  9. Posting-number: Volume 2, Issue 3
  10. Archive-name: lavg_tools/part01
  11.  
  12. Greetings, humanoids.
  13.  
  14. Just got Lenny Tropiano's sysinfo package from osu-cis, and for the fun of
  15. it, decided to write a few things to utilize the load average daemon
  16. (/etc/loadavgd) that comes with sysinfo.  To that end, I've come up with
  17. getloadavg(3), which includes a man page, and uptime(1), which doesn't yet
  18. include a man (I'm working on it...)
  19.  
  20. I'm also working on a port of BSD w(1), but am running into some trouble.
  21. Any help you out there on the Net can render (which of course includes
  22. source code ;-) ) would be greatly appreciated.
  23.  
  24. I can be reached at dburr@sbphy.physics.ucsb.edu.  Attempting a reply via
  25. UUCP is still pretty hairy at this point.
  26.  
  27. Share And Enjoy!
  28.  
  29. ---cut here---
  30. #! /bin/sh
  31. # This is a shell archive.  Remove anything before this line, then unpack
  32. # it by saving it into a file and typing "sh file".  To overwrite existing
  33. # files, type "sh file -c".  You can also feed this as standard input via
  34. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  35. # will see the following message at the end:
  36. #        "End of archive 1 (of 1)."
  37. # Contents:  MANIFEST Makefile README getloadavg.3 getloadavg.c
  38. #   uptime.c
  39. # Wrapped by dburr@sbanet on Tue May 26 13:51:19 1992
  40. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  41. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  42.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  43. else
  44. echo shar: Extracting \"'MANIFEST'\" \(434 characters\)
  45. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  46. X   File Name        Archive #    Description
  47. X-----------------------------------------------------------
  48. X MANIFEST                   1    This shipping list
  49. X Makefile                   1    File for make(1) to build this.
  50. X README                     1    Read this first!!
  51. X getloadavg.3               1    Man page for getloadavg() call
  52. X getloadavg.c               1    Source for getloadavg() call
  53. X uptime.c                   1    Source for uptime(1) program
  54. END_OF_FILE
  55. if test 434 -ne `wc -c <'MANIFEST'`; then
  56.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  57. fi
  58. # end of 'MANIFEST'
  59. fi
  60. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  61.   echo shar: Will not clobber existing file \"'Makefile'\"
  62. else
  63. echo shar: Extracting \"'Makefile'\" \(1053 characters\)
  64. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  65. X# $Id: Makefile,v 1.1 1992/05/26 20:49:22 dburr Exp $
  66. X#
  67. X# $Log: Makefile,v $
  68. X# Revision 1.1  1992/05/26  20:49:22  dburr
  69. X# Initial revision
  70. X#
  71. X#
  72. X# makefile for loadavg package
  73. X# By Donald Burr <dburr@sbphy.physics.ucsb.edu>
  74. X# Copyright (c) 1992
  75. X
  76. XSHELL        = /bin/sh
  77. X
  78. XCC        = cc
  79. XCFLAGS        = -g
  80. XLDFLAGS        =
  81. XLIBS        =
  82. X
  83. XINSTDIR        = /usr/local/bin
  84. XLIBDIR        = /usr/lib
  85. XMANDIR        = /usr/local/man/man3
  86. XMANEXT        = 3
  87. X
  88. XRANLIB        = echo
  89. X
  90. Xall:        uptime libloadavg.a
  91. X
  92. Xuptime:        uptime.o
  93. X        $(CC) $(CFLAGS) $(LDFLAGS) -o uptime uptime.o $(LIBS)
  94. X
  95. Xlibloadavg.a:    getloadavg.o
  96. X        ar cr libloadavg.a getloadavg.o
  97. X        $(RANLIB) libloadavg.a
  98. X
  99. Xuptime.o:    uptime.c
  100. X        $(CC) $(CFLAGS) -c uptime.c
  101. X
  102. Xgetloadavg.o:    getloadavg.c
  103. X        $(CC) $(CFLAGS) -c getloadavg.c
  104. X
  105. Xinstall:    uptime libloadavg.a
  106. X        cp ./uptime $(INSTDIR)/uptime
  107. X        cp ./libloadavg.a $(LIBDIR)
  108. X        $(RANLIB) $(LIBDIR)/libloadavg.a
  109. X        cp ./getloadavg.3 $(MANDIR)/getloadavg.$(MANEXT)
  110. X
  111. Xclean:
  112. X        rm -f *.o libloadavg.a uptime
  113. X
  114. Xdist:        
  115. X        -/bin/rm -f MANIFEST* Part*
  116. X        makekit -s20k -i FILES -o MANIFEST \
  117. X            -t"Before you do anything, read the README."
  118. END_OF_FILE
  119. if test 1053 -ne `wc -c <'Makefile'`; then
  120.     echo shar: \"'Makefile'\" unpacked with wrong size!
  121. fi
  122. # end of 'Makefile'
  123. fi
  124. if test -f 'README' -a "${1}" != "-c" ; then 
  125.   echo shar: Will not clobber existing file \"'README'\"
  126. else
  127. echo shar: Extracting \"'README'\" \(1676 characters\)
  128. sed "s/^X//" >'README' <<'END_OF_FILE'
  129. X$Id: README,v 1.1 1992/05/26 20:49:22 dburr Exp $
  130. X
  131. XLoad Average Utility Package 1.0 for AT&T UNIX-PC
  132. XBy Donald Burr <dburr@sbphy.physics.ucsb.edu>
  133. XCopyright (c) 1992.
  134. X
  135. X
  136. XWHAT IS IT?
  137. X     If you installed Lenny Tropiano's sysinfo package, you know that the
  138. XAT&T UNIX-PC can provide system load average information to your programs
  139. X(i.e. sysinfo itself).  The sysinfo package includes a load average daemon
  140. X(/etc/loadavgd) that computes the system load average every 15 seconds (I
  141. Xthink) and updates a shared memory segment.
  142. X
  143. X     Unfortunately, reading this shared memory segment is a little tricky.
  144. XYou have to insert a copy of the memory read code into every program that
  145. Xwants to read the system load average.  Either that, or put it into a
  146. Xshared library or something.
  147. X
  148. X     To this end, I have created this package.  It contains a version of the
  149. XSunOS (BSD in general?) getloadavg(3) function, that uses the shared memory
  150. Xsegment of loadavgd.  It also includes a man page.  As a bonus, I have
  151. Xincluded a version of the BSD uptime(1) command, that prints the load
  152. Xaverage.
  153. X
  154. X     I am currently working on an implementation of the BSD w(1) command.
  155. XThis will probably be bundled in with this package.
  156. X
  157. X     To compile, simply type "make".  You may want to edit the Makefile,
  158. Xto make sure the binaries, man pages, etc. are being installed in the right
  159. Xplace.
  160. X
  161. X     Comments, criticism, questions, etc. are welcome.  Send them to me at
  162. Xdburr@sbphy.physics.ucsb.edu.
  163. X
  164. X     Last, but not least, this code is in the public domain.  Feel free to
  165. Xdo whatever you want with it, but if you modify it, please leave my name,
  166. Xcopyright, RCS messages, etc. intact.
  167. X
  168. X     Share and Enjoy!
  169. END_OF_FILE
  170. if test 1676 -ne `wc -c <'README'`; then
  171.     echo shar: \"'README'\" unpacked with wrong size!
  172. fi
  173. # end of 'README'
  174. fi
  175. if test -f 'getloadavg.3' -a "${1}" != "-c" ; then 
  176.   echo shar: Will not clobber existing file \"'getloadavg.3'\"
  177. else
  178. echo shar: Extracting \"'getloadavg.3'\" \(981 characters\)
  179. sed "s/^X//" >'getloadavg.3' <<'END_OF_FILE'
  180. X'''
  181. X''' $Id: getloadavg.3,v 1.1 1992/05/26 20:49:22 dburr Exp $
  182. X'''
  183. X''' $Log: getloadavg.3,v $
  184. X''' Revision 1.1  1992/05/26  20:49:22  dburr
  185. X''' Initial revision
  186. X'''
  187. X.TH GETLOADAVG 3  "March 14, 1989"
  188. X.UC 4
  189. X.SH NAME
  190. Xgetloadavg \- get system load averages
  191. X.SH SYNOPSIS
  192. X.nf
  193. X.B getloadavg(loadavg, nelem)
  194. X.B double loadavg[nelem];
  195. X.B int nelem;
  196. X.fi
  197. X.SH DESCRIPTION
  198. X.I Getloadavg
  199. Xreturns the number of processes in the system run queue
  200. Xaveraged over various periods of time.  Up to
  201. X.I nelem
  202. Xsamples are retrieved and assigned to successive elements of
  203. X.I loadavg[].
  204. XThe system imposes a maximum of 3 samples, representing averages
  205. Xover the last 1, 5, and 15 minutes, respectively.
  206. X.SH "SEE ALSO"
  207. Xuptime(1), nlist(3), kmem(4)
  208. X.SH DIAGNOSTICS
  209. XIf the load average was unobtainable, \-1 is returned; otherwise,
  210. Xthe number of samples actually retrieved is returned.
  211. X.SH BUGS
  212. XPrograms using this utility must have read permission on
  213. X.I /dev/kmem.
  214. XThis restriction will eventually be lifted.
  215. END_OF_FILE
  216. if test 981 -ne `wc -c <'getloadavg.3'`; then
  217.     echo shar: \"'getloadavg.3'\" unpacked with wrong size!
  218. fi
  219. # end of 'getloadavg.3'
  220. fi
  221. if test -f 'getloadavg.c' -a "${1}" != "-c" ; then 
  222.   echo shar: Will not clobber existing file \"'getloadavg.c'\"
  223. else
  224. echo shar: Extracting \"'getloadavg.c'\" \(1170 characters\)
  225. sed "s/^X//" >'getloadavg.c' <<'END_OF_FILE'
  226. X/*
  227. X * $Id: getloadavg.c,v 1.1 1992/05/26 20:49:22 dburr Exp $
  228. X *
  229. X * $Log: getloadavg.c,v $
  230. X * Revision 1.1  1992/05/26  20:49:22  dburr
  231. X * Initial revision
  232. X *
  233. X *
  234. X * getloadavg() -- get average number of processes in system run queue
  235. X *                 over various periods of time
  236. X *
  237. X * Donald Burr, 1992
  238. X *
  239. X * This simulates the BSD getloadavg() call, using the SysV loadavgd package.
  240. X *
  241. X */
  242. X
  243. X#include <stdio.h>
  244. X#include <fcntl.h>
  245. X#include <errno.h>
  246. X#include <signal.h>
  247. X#include <sys/types.h>
  248. X#include <sys/stat.h>
  249. X#include <sys/param.h>
  250. X#include <sys/ipc.h>
  251. X#include <sys/shm.h>
  252. X#include <utmp.h>
  253. X#include <setjmp.h>
  254. X#include <time.h>
  255. X
  256. X#ifndef ctob            /* For System V */
  257. X#include <sys/sysmacros.h>
  258. X#endif
  259. X
  260. Xint    shm;
  261. X
  262. Xint    getloadavg(loadavg, nelem)
  263. Xdouble    loadavg[];
  264. Xint    nelem;
  265. X{
  266. X    int        i;
  267. X    double           *shmseg;
  268. X
  269. X    if (nelem > 3)
  270. X        return(-1);
  271. X
  272. X    /* grab hold of our shm segment */
  273. X    shm = shmget(ftok("/unix",'a'),12,0);
  274. X
  275. X    /* did we err? */
  276. X    if (shm==-1)  {
  277. X        for(i=0;i<3;i++)
  278. X            loadavg[i] = 0;
  279. X        return(-1);
  280. X    }
  281. X
  282. X    /* then let's do it */
  283. X    shmseg = (double *)shmat(shm, (char *)0, SHM_RDONLY);
  284. X
  285. X    for (i=0; i<nelem;i++)
  286. X        loadavg[i] = (double) shmseg[i];
  287. X
  288. X    return(nelem);
  289. X}
  290. END_OF_FILE
  291. if test 1170 -ne `wc -c <'getloadavg.c'`; then
  292.     echo shar: \"'getloadavg.c'\" unpacked with wrong size!
  293. fi
  294. # end of 'getloadavg.c'
  295. fi
  296. if test -f 'uptime.c' -a "${1}" != "-c" ; then 
  297.   echo shar: Will not clobber existing file \"'uptime.c'\"
  298. else
  299. echo shar: Extracting \"'uptime.c'\" \(5270 characters\)
  300. sed "s/^X//" >'uptime.c' <<'END_OF_FILE'
  301. X/*
  302. X * $Id: uptime.c,v 1.5 1992/05/06 18:51:50 dburr Exp $
  303. X *
  304. X * $Log: uptime.c,v $
  305. X * Revision 1.5  1992/05/06  18:51:50  dburr
  306. X * uptime was printing out "x days, 0 mins" if system has been up
  307. X * exactly X days.
  308. X *
  309. X * Revision 1.4  1992/04/20  00:31:29  dburr
  310. X * *** empty log message ***
  311. X *
  312. X * Revision 1.3  1992/04/19  19:48:12  dburr
  313. X * Added error checking during shared memory open.
  314. X * Added compiled-in RCS version strings.
  315. X *
  316. X * Revision 1.2  1992/04/19  08:47:08  dburr
  317. X * Added load average support.
  318. X * Fixed up some time printing problems.
  319. X *
  320. X * Revision 1.1  1992/04/19  07:33:16  dburr
  321. X * Initial revision
  322. X *
  323. X *
  324. X * uptime.c -- display system uptime
  325. X *
  326. X * By Donald Burr
  327. X * UUCP: uunet!nixhub!dburr
  328. X * INTERNET: dburr@sbphy.physics.ucsb.edu
  329. X *           dburr@gnu.ai.mit.edu (Back up)
  330. X *           dburr%nixhub.UUCP@uunet.uu.net
  331. X *           dburr@nixhub.UUCP
  332. X *
  333. X * Based on a program written by:
  334. X * John Levine <johnl@iecc.cambridge.ma.us>
  335. X */
  336. X
  337. X/*
  338. X *    Report system uptime
  339. X */
  340. X
  341. X/*
  342. X * Not-so-subtly modified by Donald Burr (nixhub!root):
  343. X *    - Made to look more like BSD uptime (xx:xx, up xx days, xx:xx)
  344. X *    - My system has a battery backed clock, so when it boots up, it
  345. X *      writes the *real* clock's time as the boot time.  This gets
  346. X *      pretty wild, with uptime's of several days to several years!
  347. X *      (Or even negative.)  So, instead of looking for BOOT_TIME,
  348. X *      I look for the first DEAD_PROCESS record, which is 'bcheckrc',
  349. X *      and has the correct time on it.  (It is a few seconds after the
  350. X *      real boot time, but that's close enough.)
  351. X *    - uses load average provided by /etc/ldavgd (puts it in shared
  352. X *      memory)
  353. X */
  354. X
  355. X#include <stdio.h>
  356. X#include <fcntl.h>
  357. X#include <errno.h>
  358. X#include <signal.h>
  359. X#include <sys/types.h>
  360. X#include <sys/stat.h>
  361. X#include <sys/param.h>
  362. X#include <sys/ipc.h>
  363. X#include <sys/shm.h>
  364. X#include <utmp.h>
  365. X#include <setjmp.h>
  366. X#include <time.h>
  367. X
  368. X#ifndef ctob            /* For System V */
  369. X#include <sys/sysmacros.h>
  370. X#endif
  371. X
  372. Xint    shm;
  373. X
  374. X#define HOUR    (60)
  375. X#define    DAY    (HOUR*24)
  376. X
  377. Xstruct utmp ut;
  378. X
  379. Xstruct lablk {
  380. X    double    l1, l2, l3;
  381. X};
  382. X
  383. X/* what version are we? */
  384. Xstatic char version[] = "@(#) $Id: uptime.c,v 1.5 1992/05/06 18:51:50 dburr Exp $";
  385. X
  386. Xmain(argc, argv)
  387. Xint    argc;
  388. Xchar    argv[];
  389. X{
  390. X    FILE *f = fopen(UTMP_FILE, "r"), *f2;
  391. X    time_t now = time(), btime, uptime;
  392. X    int num_users = 0, who=0, time_hour;
  393. X    struct tm *time_struct;
  394. X    char tbuf[50];
  395. X    struct utmp *ut2;
  396. X    struct lablk labuf;
  397. X
  398. X    /* argument parsing */
  399. X    if (argc <= 2)
  400. X    {
  401. X        if (!strncmp(argv[1], "-w", 2))  {
  402. X            who=1; }
  403. X    } else {
  404. X        fprintf(stderr, "usage: uptime [-w]\n");
  405. X        exit(1);
  406. X    }
  407. X
  408. X    if(who)
  409. X        fprintf(stderr, "warning: -w not supported\n");
  410. X
  411. X    /* grab hold of our shm segment */
  412. X    shm = shmget(ftok("/unix",'a'),12,0);
  413. X
  414. X    /* did we err? */
  415. X    if (shm==-1)  {
  416. X        fprintf(stderr, "warning: unable to get proper uptime info\n");
  417. X        labuf.l1 = 0; labuf.l2 = 0; labuf.l3 = 0;
  418. X    }
  419. X
  420. X    /* now get our load average */
  421. X    get_loadav(&labuf);
  422. X
  423. X    for(;;) {
  424. X        if(fread(&ut, sizeof(ut), 1, f) < 1) {
  425. X            printf("No boot time\n");
  426. X            return 1;
  427. X        }
  428. X        if(ut.ut_type == BOOT_TIME  /* was DEAD_PROCESS */ )
  429. X            break;
  430. X    }
  431. X
  432. X    setutent();
  433. X    while((ut2 = getutent()) != (struct utmp *) NULL) {
  434. X        if (ut2->ut_type == USER_PROCESS)
  435. X        {
  436. X            num_users++;
  437. X        }
  438. X    }
  439. X    endutent();
  440. X
  441. X/* Ok, here comes the tricky part.  Here are my interpretations of the rules
  442. X   uptime uses to determine what format to print in. (at least on BSD4.3 up-
  443. X   time, on a DECstation 5000 running Ultrix 4.2...
  444. X
  445. X   1.  If system has been up less than 1 hour, print "x  mins" or "1 min"
  446. X   2.  If system has been up exactly X hours, print "x  hrs" or "1 hr"
  447. X   3.  If system has been up more than 1 hour, 1 minute, just print
  448. X       "x:xx"
  449. X   4.  If system has been up exactly X day(s), print "x  days" or "1 day"
  450. X   5.  If system has been up exactly X day(s), Y min(s), print
  451. X       "x  days,  y  mins"                                               */
  452. X
  453. X    btime = ut.ut_time;
  454. X    uptime = (now - btime)/60;        /* in seconds */
  455. X    time_struct = localtime(&now);    /* btime for boot time */
  456. X
  457. X    time_hour = time_struct->tm_hour;
  458. X
  459. X    if(time_struct->tm_hour > 12)
  460. X        time_hour = time_struct->tm_hour - 12;
  461. X
  462. X    time_hour = (time_hour == 0 ? 12 : time_hour);
  463. X
  464. X    printf("  %s%d:%02d%s  up ",
  465. X        (((time_hour > 9) && (time_struct->tm_hour != 0)) ? "" : " "),
  466. X        time_hour,
  467. X        time_struct->tm_min,
  468. X        (time_struct->tm_hour >= 12 ?
  469. X            "pm" : "am"));
  470. X    if(uptime >= DAY) {
  471. X        printf("%d day%s, ", uptime/DAY, (uptime>(2*DAY))?"s":"");
  472. X        uptime = uptime%DAY;
  473. X    }
  474. X
  475. X    if ((uptime/HOUR == 0) && (uptime%HOUR != 0))
  476. X        printf("%d min%s,  ", uptime%HOUR,
  477. X            (uptime%HOUR > 1 ?
  478. X                "s" : ""));        /* Rule #1 */
  479. X    else if (uptime%HOUR == 0)
  480. X        printf("%d hr%s,  ", uptime/HOUR,
  481. X            (uptime/HOUR > 1 ?
  482. X                "s" : ""));        /* Rule #2 */
  483. X    else
  484. X    printf("%d:%02d,  ", uptime/HOUR, uptime%HOUR);    /* Rule #3 */
  485. X/*    printf("%d hour%s, %d min%s,  ", uptime/HOUR,
  486. X        (uptime/HOUR > 1 ? "s" : ""),
  487. X        uptime%HOUR,
  488. X        (uptime%HOUR > 1 ? "s" : "")); */
  489. X
  490. X    printf("%d user%s,  load average:  %4.2f, %4.2f, %4.2f\n",
  491. X        num_users, (num_users > 1 ? "s" : ""), labuf.l1,
  492. X        labuf.l2, labuf.l3);
  493. X}
  494. X
  495. Xget_loadav(lbuf)
  496. Xstruct lablk *lbuf;
  497. X{
  498. X    double    *shmseg;
  499. X
  500. X    shmseg = (double *)shmat(shm, (char *) 0, SHM_RDONLY);
  501. X    lbuf->l1 = shmseg[0];
  502. X    lbuf->l2 = shmseg[1];
  503. X    lbuf->l3 = shmseg[2];
  504. X    shmdt(shmseg);
  505. X}
  506. END_OF_FILE
  507. if test 5270 -ne `wc -c <'uptime.c'`; then
  508.     echo shar: \"'uptime.c'\" unpacked with wrong size!
  509. fi
  510. # end of 'uptime.c'
  511. fi
  512. echo shar: End of archive 1 \(of 1\).
  513. cp /dev/null ark1isdone
  514. MISSING=""
  515. for I in 1 ; do
  516.     if test ! -f ark${I}isdone ; then
  517.     MISSING="${MISSING} ${I}"
  518.     fi
  519. done
  520. if test "${MISSING}" = "" ; then
  521.     echo You have the archive.
  522.     echo "Before you do anything, read the README."
  523.     rm -f ark[1-9]isdone
  524. else
  525.     echo You still need to unpack the following archives:
  526.     echo "        " ${MISSING}
  527. fi
  528. ##  End of shell archive.
  529. exit 0
  530. ---cut here---
  531.  
  532. +-----------------------------------+-----------------------------------------+
  533. : Donald Burr, Coordinator          : dburr@sbphy.physics.ucsb.edu   INTERNET :
  534. : Santa Barbara Area Network(SBANET): dburr@gnu.ai.mit.edu (Backup)  ======== :
  535. : Santa Barbara, CA  USA            : dburr%sbanet.UUCP@uunet.uu.net (NOT YET):
  536. : uunet!dsc.com!dschub!sbanet!dburr : America OnLine: DonaldBurr              :
  537. +-----------------------------------+-----------------------------------------+
  538. -- 
  539. David H. Brierley
  540. Home: dave@galaxia.newport.ri.us; Work: dhb@quahog.ssd.ray.com
  541. Send comp.sources.3b1 submissions to comp-sources-3b1@galaxia.newport.ri.us
  542. %% Can I be excused, my brain is full. **
  543.