bobs%moose@rand.org (Robert Schwartzkopf) (06/09/90)
Submitted-by: Robert Schwartzkopf <bobs%moose@rand.org> Posting-number: Volume 7, Issue 87 Archive-name: xmeter/patch2 Patch-To: xmeter: Volume 6, Issue 98 Patch-To: xmeter: Volume 7, Issue 34 (patch 1) This patch includes many bug fixes suggested by various people. My thanks to everyone who took the time to find the bugs and report them. Bob Schwartzkopf (bobs@rand.org) # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # patch2 # This archive created: Thu Jun 7 16:33:40 1990 echo shar: extracting patch2 sed 's/^XX//' << \SHAR_EOF > patch2 XX*** /tmp/,RCSt1a14009 Thu Jun 7 16:32:02 1990 XX--- patchlevel.h Thu Jun 7 16:25:06 1990 XX*************** XX*** 1 **** XX! #define PATCHLEVEL 1 XX--- 1 ---- XX! #define PATCHLEVEL 2 XX*** /tmp/,RCSt1a14045 Thu Jun 7 16:32:37 1990 XX--- xmeter.c Thu Jun 7 16:23:26 1990 XX*************** XX*** 5,19 **** XX * XX * Suggestions for improvements and bug fixes can be sent to "bobs@rand.org". XX * As my schedule permits I'll try to incorporate them. xmeter is known XX! * to run under X11 R4 on sun3s and sun4s running SunOS 4.0.3. XX */ XX XX #ifndef lint XX! static char *RCSid="$Header: /tmp_mnt/home/src/rand/xmeter/RCS/xmeter.c,v 1.2 90/05/04 12:31:52 bobs Exp $"; XX #endif lint XX XX /* XX * $Log: xmeter.c,v $ XX * Revision 1.2 90/05/04 12:31:52 bobs XX * Fix memory leak in getport(). Wasn't freeing resources allocated by XX * clntudp_create when clnt_call failed. Also removed explicit calls XX--- 5,30 ---- XX * XX * Suggestions for improvements and bug fixes can be sent to "bobs@rand.org". XX * As my schedule permits I'll try to incorporate them. xmeter is known XX! * to run under X11 R4 on sun3s and sun4s running SunOS 4.0.3, 4.1. XX */ XX XX #ifndef lint XX! static char *RCSid="$Header: /tmp_mnt/home/src/rand/xmeter/RCS/xmeter.c,v 1.3 90/06/07 16:17:06 bobs Exp $"; XX #endif lint XX XX /* XX * $Log: xmeter.c,v $ XX+ * Revision 1.3 90/06/07 16:17:06 bobs XX+ * Removed "retries". XX+ * Changed name of paned widgets to host name displayed in that widget. XX+ * Used actual time between rstat calls instead of "update" interval in XX+ * computing rates in functions that return values to stripchart widgets. XX+ * Removed "ost" variable, rewrote functions that return values to XX+ * stripcharts. XX+ * Fixed bug in fsys, fcpu and fuser that could cause divide by 0 errors. XX+ * Fixed rpc timeout handling in getmeter and getport. XX+ * Use RSTATVERS_TIME instead of RSTATVERS, which isn't defined in SunOS 4.1. XX+ * XX * Revision 1.2 90/05/04 12:31:52 bobs XX * Fix memory leak in getport(). Wasn't freeing resources allocated by XX * clntudp_create when clnt_call failed. Also removed explicit calls XX*************** XX*** 63,68 **** XX--- 74,80 ---- XX int idx; /* Index into st array */ XX int refcnt; /* Meters sharing this structure */ XX int curcnt; /* Meters who've displayed current data */ XX+ int first; /* TRUE when only 1 rstat has been done */ XX struct shmeter *nxt; /* Link these together */ XX } SHMETER; XX XX*************** XX*** 136,142 **** XX int errorLevel; XX XtOrientation orientation; XX int timeout; XX- int retries; XX int update; XX short width; XX int loadscaledef = FSCALE; XX--- 148,153 ---- XX*************** XX*** 147,154 **** XX (Cardinal) &width, XtRString, "80"}, XX {"timeout", "Timeout", XtRInt, sizeof (int), XX (Cardinal) &timeout, XtRString, "5"}, XX- {"retries", "Retries", XtRInt, sizeof (int), XX- (Cardinal) &retries, XtRString, "2"}, XX {"okBack", "OkBack", XtRPixel, sizeof (Pixel), XX (Cardinal) &back[OK], XtRString, "white"}, XX {"warnBack", "WarnBack", XtRPixel, sizeof (Pixel), XX--- 158,163 ---- XX*************** XX*** 195,201 **** XX static char *progname; XX static XrmOptionDescRec options[] = { XX {"-timeout", "timeout", XrmoptionSepArg, NULL}, XX- {"-retries", "retries", XrmoptionSepArg, NULL}, XX {"-orientation", "orientation", XrmoptionSepArg, NULL}, XX {"-okBack", "okBack", XrmoptionSepArg, NULL}, XX {"-warnBack", "warnBack", XrmoptionSepArg, NULL}, XX--- 204,209 ---- XX*************** XX*** 228,234 **** XX {XtNresizable, TRUE }, /* Resizable */ XX }; XX static struct timeval ptto = {0, 0}; XX- static struct timeval tto = {0, 0}; XX static Arg args[20]; XX static SHMETER *shmeters = NULL; XX XX--- 236,241 ---- XX*************** XX*** 241,247 **** XX Widget toplevel; XX Widget form; XX Widget meter; XX- Widget label; XX Widget pane = NULL; XX int i; XX int n; XX--- 248,253 ---- XX*************** XX*** 257,263 **** XX XtGetApplicationResources (toplevel, NULL, application_resources, XX XtNumber (application_resources), NULL, 0); XX ptto.tv_sec = timeout; XX- tto.tv_sec = retries * timeout; XX form = XtCreateManagedWidget ("form", formWidgetClass, toplevel, XX formargs, XtNumber (formargs)); XX if (argc < 2) XX--- 263,268 ---- XX*************** XX*** 271,284 **** XX n = 0; XX XtSetArg (args[n], orient, pane); n++; XX XtSetArg (args[n], XtNwidth, width); n++; XX! pane = XtCreateManagedWidget ("paned", panedWidgetClass, form, args, n); XX n = 0; XX XtSetArg (args[n], XtNshowGrip, XtEno); n++; XX XtSetArg (args[n], XtNlabel, h->label); n++; XX XtSetArg (args[n], XtNbackground, back[OK]); n++; XX! label = XtCreateManagedWidget ("label", labelWidgetClass, XX! pane, args, n); XX! h->labelwidget = label; XX n = 0; XX XtSetArg (args[n], orient, meter); n++; XX XtSetArg (args[n], XtNresizable, TRUE); n++; XX--- 276,289 ---- XX n = 0; XX XtSetArg (args[n], orient, pane); n++; XX XtSetArg (args[n], XtNwidth, width); n++; XX! pane = XtCreateManagedWidget (h->sh->name, panedWidgetClass, XX! form, args, n); XX n = 0; XX XtSetArg (args[n], XtNshowGrip, XtEno); n++; XX XtSetArg (args[n], XtNlabel, h->label); n++; XX XtSetArg (args[n], XtNbackground, back[OK]); n++; XX! h->labelwidget = XtCreateManagedWidget ("label", labelWidgetClass, XX! pane, args, n); XX n = 0; XX XtSetArg (args[n], orient, meter); n++; XX XtSetArg (args[n], XtNresizable, TRUE); n++; XX*************** XX*** 342,353 **** XX *(double *) data = s == FATAL ? 0.0 : (double) l / sd[h->stat].scale; XX sh = h->sh; XX if (s != h->oldstate) { XX! n = 0; /* Change background in pane widget */ XX XtSetArg (args[n], XtNbackground, back[s]); n++; XX XtSetValues (w, args, n); XX! n = 0; /* Change background in label widget */ XX XtSetArg (args[n], XtNbackground, back[s]); n++; XX! if (s == FATAL || h->oldstate == FATAL) { /* Change label too */ XX sprintf (h->label, "%s %s", sh->name, XX s == FATAL ? DMSG : sd[h->stat].name); XX XtSetArg (args[n], XtNlabel, h->label); n++; XX--- 347,358 ---- XX *(double *) data = s == FATAL ? 0.0 : (double) l / sd[h->stat].scale; XX sh = h->sh; XX if (s != h->oldstate) { XX! n = 0; /* Change background in stripchart widget */ XX XtSetArg (args[n], XtNbackground, back[s]); n++; XX XtSetValues (w, args, n); XX! n = 0; /* Update label widget */ XX XtSetArg (args[n], XtNbackground, back[s]); n++; XX! if (s == FATAL || h->oldstate == FATAL) { XX sprintf (h->label, "%s %s", sh->name, XX s == FATAL ? DMSG : sd[h->stat].name); XX XtSetArg (args[n], XtNlabel, h->label); n++; XX*************** XX*** 382,392 **** XX * value and the previous value, and dividing by the update interval in XX * order to get the current rate. XX */ XX XX! int fuser (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX int i; XX--- 387,398 ---- XX * value and the previous value, and dividing by the update interval in XX * order to get the current rate. XX */ XX+ #define DIF(m,fld) (m->sh->st[m->sh->idx].fld - \ XX+ m->sh->st[m->sh->idx ^ 1].fld) XX XX! int fuser (h) XX XX! METER *h; XX XX { XX int i; XX*************** XX*** 393,410 **** XX int t; XX int d[CPUSTATES]; XX XX! if (ost) { XX! for (t = 0, i= 0; i < CPUSTATES; i++) XX! t += (d[i] = h->sh->st[h->sh->idx].cp_time[i] - ost->cp_time[i]); XX! return ((100 * (d[CP_USER] + d[CP_NICE])) / t); XX! } else XX! return (0); XX } XX XX! int fsys (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX int i; XX--- 399,412 ---- XX int t; XX int d[CPUSTATES]; XX XX! for (t = 0, i= 0; i < CPUSTATES; i++) XX! t += (d[i] = DIF (h, cp_time[i])); XX! return (t ? (100 * (d[CP_USER] + d[CP_NICE])) / t : 0); XX } XX XX! int fsys (h) XX XX! METER *h; XX XX { XX int i; XX*************** XX*** 411,428 **** XX int t; XX int d[CPUSTATES]; XX XX! if (ost) { XX! for (t = 0, i= 0; i < CPUSTATES; i++) XX! t += (d[i] = h->sh->st[h->sh->idx].cp_time[i] - ost->cp_time[i]); XX! return ((100 * d[CP_SYS]) / t); XX! } else XX! return (0); XX } XX XX! int fcpu (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX int i; XX--- 413,426 ---- XX int t; XX int d[CPUSTATES]; XX XX! for (t = 0, i= 0; i < CPUSTATES; i++) XX! t += (d[i] = DIF (h, cp_time[i])); XX! return (t ? (100 * d[CP_SYS]) / t : 0); XX } XX XX! int fcpu (h) XX XX! METER *h; XX XX { XX int i; XX*************** XX*** 429,545 **** XX int t; XX int d[CPUSTATES]; XX XX! if (ost) { XX! for (t = 0, i= 0; i < CPUSTATES; i++) XX! t += (d[i] = h->sh->st[h->sh->idx].cp_time[i] - ost->cp_time[i]); XX! return ((100 * (d[CP_USER]+d[CP_NICE]+d[CP_SYS])) / t); XX! } else XX! return (0); XX } XX XX! int fpgpgin (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].v_pgpgin - ost->v_pgpgin) / update : 0); XX } XX XX! int fpgpgout (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].v_pgpgout - ost->v_pgpgout) / update : 0); XX } XX XX! int fpswpin (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].v_pswpin - ost->v_pswpin) / update : 0); XX } XX XX! int fpswpout (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].v_pswpout - ost->v_pswpout) / update : 0); XX } XX XX! int fintr (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].v_intr - ost->v_intr) / update : 0); XX } XX XX! int fipkt (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].if_ipackets - ost->if_ipackets) / update : 0); XX } XX XX! int fierr (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].if_ierrors - ost->if_ierrors) / update : 0); XX } XX XX! int fopkt (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].if_opackets - ost->if_opackets)/update : 0); XX } XX XX! int foerr (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].if_oerrors - ost->if_oerrors) / update : 0); XX } XX XX! int fcoll (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].if_collisions - ost->if_collisions) / update : 0); XX } XX XX! int fswt (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX! return (ost ? (h->sh->st[h->sh->idx].v_swtch - ost->v_swtch) / update : 0); XX } XX XX! int fload (h, ost) XX XX! METER *h; XX! struct statstime *ost; XX XX { XX return (h->sh->st[h->sh->idx].avenrun[0]); XX--- 427,528 ---- XX int t; XX int d[CPUSTATES]; XX XX! for (t = 0, i= 0; i < CPUSTATES; i++) XX! t += (d[i] = DIF (h, cp_time[i])); XX! return (t ? (100 * (d[CP_USER]+d[CP_NICE]+d[CP_SYS])) / t : 0); XX } XX XX! int fpgpgin (h) XX XX! METER *h; XX XX { XX! return (DIF (h, v_pgpgin) / DIF (h, curtime.tv_sec)); XX } XX XX! int fpgpgout (h) XX XX! METER *h; XX XX { XX! return (DIF (h, v_pgpgout) / DIF (h, curtime.tv_sec)); XX } XX XX! int fpswpin (h) XX XX! METER *h; XX XX { XX! return (DIF (h, v_pswpin) / DIF (h, curtime.tv_sec)); XX } XX XX! int fpswpout (h) XX XX! METER *h; XX XX { XX! return (DIF (h, v_pswpout) / DIF (h, curtime.tv_sec)); XX } XX XX! int fintr (h) XX XX! METER *h; XX XX { XX! return (DIF (h, v_intr) / DIF (h, curtime.tv_sec)); XX } XX XX! int fipkt (h) XX XX! METER *h; XX XX { XX! return (DIF (h, if_ipackets) / DIF (h, curtime.tv_sec)); XX } XX XX! int fierr (h) XX XX! METER *h; XX XX { XX! return (DIF (h, if_ierrors) / DIF (h, curtime.tv_sec)); XX } XX XX! int fopkt (h) XX XX! METER *h; XX XX { XX! return (DIF (h, if_opackets) / DIF (h, curtime.tv_sec)); XX } XX XX! int foerr (h) XX XX! METER *h; XX XX { XX! return (DIF (h, if_oerrors) / DIF (h, curtime.tv_sec)); XX } XX XX! int fcoll (h) XX XX! METER *h; XX XX { XX! return (DIF (h, if_collisions) / DIF (h, curtime.tv_sec)); XX } XX XX! int fswt (h) XX XX! METER *h; XX XX { XX! return (DIF (h, v_swtch) / DIF (h, curtime.tv_sec)); XX } XX XX! int fload (h) XX XX! METER *h; XX XX { XX return (h->sh->st[h->sh->idx].avenrun[0]); XX*************** XX*** 548,554 **** XX /* XX * getmeter - Executes rstat(3) call to read statistics for specified host. XX * I do all the rpc junk myself so that I have better control over timeouts XX! * and retries than rstat(3) gives me. If we're watching multiple stats XX * on the same host I only do one rstat(3) call (refcnt and curcnt are XX * used for this). XX */ XX--- 531,537 ---- XX /* XX * getmeter - Executes rstat(3) call to read statistics for specified host. XX * I do all the rpc junk myself so that I have better control over timeouts XX! * than rstat(3) gives me. If we're watching multiple stats XX * on the same host I only do one rstat(3) call (refcnt and curcnt are XX * used for this). XX */ XX*************** XX*** 558,565 **** XX XX { XX enum clnt_stat cs; XX- struct statstime *ost; XX register SHMETER *sh; XX XX sh = h->sh; XX if (sh->curcnt >= sh->refcnt) XX--- 541,548 ---- XX XX { XX enum clnt_stat cs; XX register SHMETER *sh; XX+ int p; XX XX sh = h->sh; XX if (sh->curcnt >= sh->refcnt) XX*************** XX*** 566,585 **** XX sh->curcnt = 0; XX if (!sh->curcnt++) { XX if (sh->clnt == NULL) { XX! if ((sh->addr.sin_port = getport (h)) < 0) XX return (-1); XX sh->s = RPC_ANYSOCK; XX! if (!(sh->clnt = clntudp_create (&sh->addr, RSTATPROG, RSTATVERS, XX ptto, &sh->s))) XX return (-1); XX! ost = NULL; XX sh->idx = 0; XX } else { XX! ost = &sh->st[sh->idx]; XX sh->idx ^= 1; XX } XX cs = clnt_call (sh->clnt, RSTATPROC_STATS, xdr_void, 0, xdr_statstime, XX! &sh->st[sh->idx], tto); XX if (cs != RPC_SUCCESS) { XX clnt_destroy (sh->clnt); XX sh->clnt = NULL; XX--- 549,569 ---- XX sh->curcnt = 0; XX if (!sh->curcnt++) { XX if (sh->clnt == NULL) { XX! if ((p = getport (h)) < 0) XX return (-1); XX+ sh->addr.sin_port = p; XX sh->s = RPC_ANYSOCK; XX! if (!(sh->clnt = clntudp_create(&sh->addr, RSTATPROG, RSTATVERS_TIME, XX ptto, &sh->s))) XX return (-1); XX! sh->first = 1; XX sh->idx = 0; XX } else { XX! sh->first = 0; XX sh->idx ^= 1; XX } XX cs = clnt_call (sh->clnt, RSTATPROC_STATS, xdr_void, 0, xdr_statstime, XX! &sh->st[sh->idx], ptto); XX if (cs != RPC_SUCCESS) { XX clnt_destroy (sh->clnt); XX sh->clnt = NULL; XX*************** XX*** 586,592 **** XX return (-1); XX } XX } XX! return (sh->clnt == NULL ? -1 : (sd[h->stat].val) (h, ost)); XX } XX XX /* XX--- 570,577 ---- XX return (-1); XX } XX } XX! return (sh->first ? 0 : XX! sh->clnt == NULL ? -1 : (sd[h->stat].val) (h)); XX } XX XX /* XX*************** XX*** 599,605 **** XX { XX CLIENT *c; XX enum clnt_stat cs; XX! static struct pmap pm = {RSTATPROG, RSTATVERS, IPPROTO_UDP, 0}; XX short p; XX register SHMETER *sh; XX XX--- 584,590 ---- XX { XX CLIENT *c; XX enum clnt_stat cs; XX! static struct pmap pm = {RSTATPROG, RSTATVERS_TIME, IPPROTO_UDP, 0}; XX short p; XX register SHMETER *sh; XX XX*************** XX*** 608,614 **** XX sh->addr.sin_port = htons (PMAPPORT); XX if (!(c = clntudp_create (&sh->addr, PMAPPROG, PMAPVERS, ptto, &sh->s))) XX return (-1); XX! cs = clnt_call (c, PMAPPROC_GETPORT, xdr_pmap, &pm, xdr_u_short, &p, tto); XX clnt_destroy (c); XX return (cs == RPC_SUCCESS ? p : -1); XX } XX--- 593,599 ---- XX sh->addr.sin_port = htons (PMAPPORT); XX if (!(c = clntudp_create (&sh->addr, PMAPPROG, PMAPVERS, ptto, &sh->s))) XX return (-1); XX! cs = clnt_call (c, PMAPPROC_GETPORT, xdr_pmap, &pm, xdr_u_short, &p, ptto); XX clnt_destroy (c); XX return (cs == RPC_SUCCESS ? p : -1); XX } XX*** /tmp/,RCSt1a14050 Thu Jun 7 16:32:55 1990 XX--- xmeter.man Thu Jun 7 16:13:46 1990 XX*************** XX*** 17,29 **** XX .PP XX .TP 8 XX .B \-timeout \fIseconds\fP XX! This option specifies the timeout between retries for rpc calls to the XX remote rstatd(8). The default is 5 seconds. XX- .PP XX- .TP 8 XX- .B \-retries \fIinteger\fP XX- This option specifies the total number of retries for rpc calls before XX- assuming a host is down. The default is 2. XX .PP XX .TP 8 XX .B \-orientation \fIorientation\fP XX--- 17,24 ---- XX .PP XX .TP 8 XX .B \-timeout \fIseconds\fP XX! This option specifies the timeout between rpc calls to the XX remote rstatd(8). The default is 5 seconds. XX .PP XX .TP 8 XX .B \-orientation \fIorientation\fP SHAR_EOF if test 16505 -ne "`wc -c patch2`" then echo shar: error transmitting patch2 '(should have been 16505 characters)' fi # End of shell archive exit 0 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.