openbsd-ports/sysutils/wmmon/patches/patch-wmmon_wmmon_c
ckuethe 9c0f4da318 When removable devices like USB disks are connected or disconnected, wmmon
will spin and complain that it is unable to allocate memory for diskstats.
This patch fixes that.
ok steven
2006-09-23 15:49:36 +00:00

528 lines
13 KiB
Plaintext

$OpenBSD: patch-wmmon_wmmon_c,v 1.5 2006/09/23 15:49:36 ckuethe Exp $
--- wmmon/wmmon.c.orig Tue May 19 15:13:16 1998
+++ wmmon/wmmon.c Sat Sep 23 09:43:02 2006
@@ -28,6 +28,10 @@
Changes:
----
+ 28/09/2000 (Vladimir Popov, pva48@mail.ru)
+ * Ported to OpenBSD
+ Based on FreeBSD port by Stephen Kiernan,
+ OpenBSD top and vmstat
18/05/1998 (Antoine Nulle, warp@xs4all.nl)
* MEM/SWAP/UPTIME only updated when visible
* Using global file descriptors to reduce file
@@ -72,10 +76,20 @@
#include <fcntl.h>
#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/types.h>
+#include <limits.h>
+#include <sys/disk.h>
+#include <sys/dkstat.h>
+#include <sys/malloc.h>
+#include <sys/swap.h>
+#include <sys/sysctl.h>
+
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
@@ -100,11 +114,11 @@
/* Global Variables */
/********************/
-char *ProgName;
int stat_current = 0; /* now global */
-FILE *fp_meminfo;
-FILE *fp_stat;
-FILE *fp_loadavg;
+int ndrives;
+int pagesize;
+int pageshift;
+char errbuf[_POSIX2_LINE_MAX];
/* functions */
void usage(void);
@@ -114,17 +128,15 @@ void DrawStats_io(int *, int, int, int,
void wmmon_routine(int, char **);
-void main(int argc, char *argv[]) {
+/* OpenBSD specific functions */
+#define pagetok(size) ((size) << pageshift)
+int swapmode(long *, long *);
+int main(int argc, char *argv[])
+{
int i;
-
/* Parse Command Line */
-
- ProgName = argv[0];
- if (strlen(ProgName) >= 5)
- ProgName += (strlen(ProgName) - 5);
-
for (i=1; i<argc; i++) {
char *arg = argv[i];
@@ -155,22 +167,22 @@ void main(int argc, char *argv[]) {
}
wmmon_routine(argc, argv);
+
+ return 0;
}
-/*******************************************************************************\
-|* wmmon_routine *|
-\*******************************************************************************/
+/***************************************************************************\
+|* wmmon_routine *|
+\***************************************************************************/
typedef struct {
-
- char name[5]; /* "cpu0..cpuz", eventually.. :) */
- int his[55];
- int hisaddcnt;
+ char name[5]; /* "cpu0..cpuz", eventually.. :) */
+ int his[55];
+ int hisaddcnt;
long rt_stat;
long statlast;
long rt_idle;
long idlelast;
-
} stat_dev;
#define MAX_STAT_DEVICES (4)
@@ -182,7 +194,6 @@ char *middle_action;
int checksysdevs(void);
-void get_statistics(char *, long *, long *, long *);
void DrawActive(char *);
void update_stat_cpu(stat_dev *);
@@ -213,8 +224,9 @@ void wmmon_routine(int argc, char **argv
long istat;
long idle;
- FILE *fp;
- char temp[128];
+ int mib[2];
+ size_t size;
+ struct timeval boottime;
char *p;
int xpm_X = 0, xpm_Y = 0;
@@ -223,22 +235,36 @@ void wmmon_routine(int argc, char **argv
long ref_time = 0;
long cnt_time;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_BOOTTIME;
+ size = sizeof(boottime);
+ if ( (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) && (boottime.tv_sec != 0) ) {
+ ref_time = time(NULL);
+ online_time = ref_time - boottime.tv_sec + 30;
+ }
- fp = fopen("/proc/uptime", "r");
- fp_meminfo = fopen("/proc/meminfo", "r");
- fp_loadavg = fopen("/proc/loadavg", "r");
- fp_stat = fopen("/proc/stat", "r");
+ /* get the page size and calculate pageshift from it */
+ pagesize = sysconf(_SC_PAGESIZE);
+ pageshift = 0;
+ while (pagesize > 1) {
+ pageshift++;
+ pagesize >>= 1;
+ }
- if (fp) {
- fscanf(fp, "%ld", &online_time);
- ref_time = time(0);
- fclose(fp);
+ /* we only need the amount of log(2)1024 for our conversion */
+ pageshift -= 10;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_DISKCOUNT;
+ size = sizeof(ndrives);
+ if (sysctl(mib, 2, &ndrives, &size, NULL, 0) < 0 ) {
+ warn("could not read hw.diskcount");
+ ndrives = 0;
}
for (i=0; i<MAX_STAT_DEVICES; i++) {
- for (j=0; j<55; j++) {
+ for (j=0; j<55; j++)
stat_device[i].his[j] = 0;
- }
stat_device[i].hisaddcnt = 0;
}
@@ -246,38 +272,40 @@ void wmmon_routine(int argc, char **argv
if (RIGHT_ACTION) right_action = strdup(RIGHT_ACTION);
if (MIDDLE_ACTION) middle_action = strdup(MIDDLE_ACTION);
- strcpy(temp, "/etc/wmmonrc");
- parse_rcfile(temp, wmmon_keys);
+ parse_rcfile("/etc/wmmonrc", wmmon_keys);
- p = getenv("HOME");
- strcpy(temp, p);
- strcat(temp, "/.wmmonrc");
- parse_rcfile(temp, wmmon_keys);
-
- strcpy(temp, "/etc/wmmonrc.fixed");
- parse_rcfile(temp, wmmon_keys);
+ if ((p = getenv("HOME")) != NULL) {
+#define RCFILE "/.wmmonrc"
+ char *tmp;
- stat_online = checksysdevs();
+ if (asprintf(&tmp, "%s" RCFILE, p) != -1) {
+ parse_rcfile(tmp, wmmon_keys);
+ free(tmp);
+ }
+ }
+ parse_rcfile("/etc/wmmonrc.fixed", wmmon_keys);
+ stat_online = checksysdevs();
+
openXwindow(argc, argv, wmmon_master_xpm, wmmon_mask_bits, wmmon_mask_width, wmmon_mask_height);
/* add mouse region */
AddMouseRegion(0, 12, 13, 58, 57);
AddMouseRegion(1, 5, 5, 24, 14);
- starttime = time(0);
+ starttime = time(NULL);
nexttime = starttime + 10;
for (i=0; i<stat_online; i++) {
- get_statistics(stat_device[i].name, &k, &istat, &idle);
- stat_device[i].statlast = istat;
- stat_device[i].idlelast = idle;
+ stat_device[i].statlast = 0;
+ stat_device[i].idlelast = 0;
}
- if (stat_current == 0) DrawStats(stat_device[stat_current].his, 54, 40, 5, 58);
- if (stat_current == 1) {
+ if (stat_current == 0)
+ DrawStats(stat_device[stat_current].his, 54, 40, 5, 58);
+ if (stat_current == 1)
DrawStats_io(stat_device[stat_current].his, 54, 40, 5, 58);
- }
+
if (stat_current == 2) {
xpm_X = 64;
setMaskXY(-64, 0);
@@ -288,7 +316,7 @@ void wmmon_routine(int argc, char **argv
DrawActive(stat_device[stat_current].name);
while (1) {
- curtime = time(0);
+ curtime = time(NULL);
waitpid(0, NULL, WNOHANG);
@@ -338,7 +366,7 @@ void wmmon_routine(int argc, char **argv
/*----------- online tijd neerzetten! ----------*/
- cnt_time = time(0) - ref_time + online_time;
+ cnt_time = time(NULL) - ref_time + online_time;
/* cnt_time = uptime in seconden */
/*
@@ -405,7 +433,6 @@ void wmmon_routine(int argc, char **argv
case DestroyNotify:
XCloseDisplay(display);
exit(0);
- break;
case ButtonPress:
but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
break;
@@ -430,7 +457,6 @@ void wmmon_routine(int argc, char **argv
}
case 1:
stat_current++;
- printf("current stat is :%d\n", stat_current);
if (stat_current == stat_online)
stat_current = 0;
@@ -460,146 +486,116 @@ void wmmon_routine(int argc, char **argv
void update_stat_cpu(stat_dev *st) {
- long k, istat, idle;
+ static int sysload_mib[] = {CTL_VM, VM_LOADAVG};
+ static int cp_time_mib[] = {CTL_KERN, KERN_CPTIME};
+ struct loadavg sysload;
+ double infoload;
+ size_t size;
+ long cp_time[CPUSTATES];
+ long istat, idle;
+ int i;
- get_statistics(st->name, &k, &istat, &idle);
+ /* mostly stolen from src/usr.bin/top/machine.c */
+ size = sizeof(cp_time);
+ if (sysctl(cp_time_mib, 2, &cp_time, &size, NULL, 0) < 0)
+ warn("sysctl kern.cp_time failed");
+ size = sizeof(sysload);
+ if (sysctl(sysload_mib, 2, &sysload, &size, NULL, 0) < 0)
+ warn("sysctl failed");
+ infoload = ((double) sysload.ldavg[0]) / sysload.fscale;
+
+ for (i = 0, istat = 0; i < CPUSTATES; i++)
+ if (i != CP_IDLE) istat += cp_time[i];
+ idle = cp_time[CP_IDLE];
+
st->rt_idle = idle - st->idlelast;
st->idlelast = idle;
st->rt_stat = istat - st->statlast;
st->statlast = istat;
- st->his[54] += k;
+ st->his[54] += (long)(100 * infoload);
st->hisaddcnt += 1;
}
void update_stat_io(stat_dev *st) {
- long j, k, istat, idle;
- static long maxdiskio = 0;
+ struct diskstats *q;
+ static int io_mib[] = {CTL_HW, HW_DISKSTATS};
+ int mib[] = {CTL_HW, HW_DISKCOUNT};
+ static long maxdiskxfers = 0;
+ long xfers, rwstat;
+ size_t size;
+ int i;
- get_statistics(st->name, &k, &istat, &idle);
+ size = sizeof(ndrives);
+ if (sysctl(mib, 2, &ndrives, &size, NULL, 0) < 0 ) {
+ warn("could not read hw.diskcount");
+ return;
+ }
- st->rt_idle = idle - st->idlelast;
- st->idlelast = idle;
-
- st->rt_stat = istat - st->statlast;
- st->statlast = istat;
-
- j = st->rt_stat;
- if (maxdiskio < j) {
- maxdiskio = j;
+ size = ndrives * sizeof(struct diskstats);
+ q = malloc(size);
+ if (q == NULL)
+ err(1, NULL);
+ if (sysctl(io_mib, 2, q, &size, NULL, 0) < 0) {
+ warn("could not read hw.diskstats");
+ bzero(q, ndrives * sizeof(struct diskstats));
}
- st->rt_idle = maxdiskio - j;
- st->his[54] += st->rt_stat;
- st->hisaddcnt += 1;
-}
-
-void update_stat_mem(stat_dev *st, stat_dev *st2) {
-
- char temp[128];
- unsigned long free, shared, buffers, cached;
-
- freopen("/proc/meminfo", "r", fp_meminfo);
- while (fgets(temp, 128, fp_meminfo)) {
- if (strstr(temp, "Mem:")) {
- sscanf(temp, "Mem: %ld %ld %ld %ld %ld %ld",
- &st->rt_idle, &st->rt_stat,
- &free, &shared, &buffers, &cached);
- st->rt_idle >>= 10;
- st->rt_stat -= buffers+cached;
- st->rt_stat >>= 10;
-// break;
- }
- if (strstr(temp, "Swap:")) {
- sscanf(temp, "Swap: %ld %ld", &st2->rt_idle, &st2->rt_stat);
- st2->rt_idle >>= 10;
- st2->rt_stat >>= 10;
- break;
- }
+ for (i = 0; i < ndrives; i++) {
+ rwstat += q[i].ds_rbytes + q[i].ds_wbytes;
+ xfers += q[i].ds_rxfer + q[i].ds_wxfer;
}
-}
+ free(q);
+
+ if (st->statlast == 0)
+ st->statlast = xfers;
+ if (xfers < st->statlast)
+ xfers = st->statlast;
+ st->rt_stat = xfers - st->statlast;
+ st->statlast = xfers;
-void update_stat_swp(stat_dev *st) {
+ if (maxdiskxfers < st->rt_stat)
+ maxdiskxfers = st->rt_stat;
- char temp[128];
+ st->rt_idle = maxdiskxfers - st->rt_stat;
+ st->idlelast = 0;
- fseek(fp_meminfo, 0, SEEK_SET);
- while (fgets(temp, 128, fp_meminfo)) {
- if (strstr(temp, "Swap:")) {
- sscanf(temp, "Swap: %ld %ld", &st->rt_idle, &st->rt_stat);
- st->rt_idle >>= 10;
- st->rt_stat >>= 10;
- break;
- }
- }
-
+ st->his[54] += rwstat;
+ st->hisaddcnt += 1;
}
-/*******************************************************************************\
-|* get_statistics *|
-\*******************************************************************************/
+void update_stat_mem(stat_dev *st, stat_dev *st2) {
-void get_statistics(char *devname, long *is, long *ds, long *idle) {
+ struct vmtotal total;
+ size_t size = sizeof(total);
+ static int mib[] = { CTL_VM, VM_METER };
- int i;
- char temp[128];
- char *p;
- char *tokens = " \t\n";
- float f;
- long maxdiskio=0;
+ /* get total -- systemwide main memory usage structure */
+ if ( sysctl(mib, 2, &total, &size, NULL, 0) < 0 )
+ bzero(&total, sizeof(total));
- *is = 0;
- *ds = 0;
- *idle = 0;
+ /* FIXME: is it right to count memory like this */
+ st->rt_idle = pagetok(total.t_rm + total.t_free);
+ st->rt_stat = pagetok(total.t_rm);
- if (!strncmp(devname, "cpu", 3)) {
- fseek(fp_stat, 0, SEEK_SET);
- while (fgets(temp, 128, fp_stat)) {
- if (strstr(temp, "cpu")) {
- p = strtok(temp, tokens);
- /* 1..3, 4 == idle, we don't want idle! */
- for (i=0; i<3; i++) {
- p = strtok(NULL, tokens);
- *ds += atol(p);
- }
- p = strtok(NULL, tokens);
- *idle = atol(p);
- }
- }
- fp_loadavg = freopen("/proc/loadavg", "r", fp_loadavg);
- fscanf(fp_loadavg, "%f", &f);
- *is = (long) (100 * f);
+ if ( !swapmode(&st2->rt_stat, &st2->rt_idle) ) {
+ st2->rt_idle = 0;
+ st2->rt_stat = 0;
}
-
- if (!strncmp(devname, "i/o", 3)) {
-
- fseek(fp_stat, 0, SEEK_SET);
- while (fgets(temp, 128, fp_stat)) {
- if (strstr(temp, "disk_rio") || strstr(temp, "disk_wio")) {
- p = strtok(temp, tokens);
- /* 1..4 */
- for (i=0; i<4; i++) {
- p = strtok(NULL, tokens);
- *ds += atol(p);
- }
- }
- }
- if (*ds > maxdiskio) maxdiskio = *ds;
- }
}
-/*******************************************************************************\
-|* checksysdevs *|
-\*******************************************************************************/
+/***************************************************************************\
+|* checksysdevs *|
+\***************************************************************************/
int checksysdevs(void) {
- strcpy(stat_device[0].name, "cpu0");
- strcpy(stat_device[1].name, "i/o");
- strcpy(stat_device[2].name, "sys");
+ strncpy(stat_device[0].name, "cpu0", 5);
+ strncpy(stat_device[1].name, "i/o", 5);
+ strncpy(stat_device[2].name, "sys", 5);
return 3;
}
@@ -733,7 +729,35 @@ void usage(void) {
void printversion(void) {
- if (!strcmp(ProgName, "wmmon")) {
- fprintf(stderr, "%s\n", WMMON_VERSION);
- }
+ fprintf(stderr, "%s\n", WMMON_VERSION);
+}
+
+int swapmode(long *used, long *total) {
+ int nswap, rnswap, i;
+ struct swapent *swdev;
+
+ nswap = swapctl(SWAP_NSWAP, 0, 0);
+ if (nswap == 0)
+ return 0;
+
+ swdev = malloc(nswap * sizeof(*swdev));
+ if(swdev == NULL)
+ return 0;
+
+ rnswap = swapctl(SWAP_STATS, swdev, nswap);
+ if(rnswap == -1)
+ return 0;
+
+ /* if rnswap != nswap, then what? */
+
+ /* Total things up */
+ *total = *used = 0;
+ for (i = 0; i < nswap; i++)
+ if (swdev[i].se_flags & SWF_ENABLE) {
+ *used += (swdev[i].se_inuse / (1024/DEV_BSIZE));
+ *total += (swdev[i].se_nblks / (1024/DEV_BSIZE));
+ }
+
+ free (swdev);
+ return 1;
}