529 lines
13 KiB
Plaintext
529 lines
13 KiB
Plaintext
$OpenBSD: patch-wmmon_wmmon_c,v 1.7 2012/12/18 21:38:12 sthen Exp $
|
|
--- wmmon/wmmon.c.orig Tue May 19 15:13:16 1998
|
|
+++ wmmon/wmmon.c Thu Dec 6 15:29:36 2012
|
|
@@ -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,21 @@
|
|
#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 <sys/proc.h>
|
|
+#include <sys/disk.h>
|
|
+#include <sys/dkstat.h>
|
|
+#include <sys/malloc.h>
|
|
+#include <sys/swap.h>
|
|
+#include <sys/sysctl.h>
|
|
|
|
+#include <limits.h>
|
|
+
|
|
#include <X11/Xlib.h>
|
|
#include <X11/xpm.h>
|
|
#include <X11/extensions/shape.h>
|
|
@@ -100,11 +115,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 +129,15 @@ void DrawStats_io(int *, 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 +168,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 +195,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 +225,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 +236,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 +273,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 +317,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 +367,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 +434,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 +458,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 +487,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 +730,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;
|
|
}
|