openbsd-ports/sysutils/wmmon/patches/patch-wmmon_wmmon_c

438 lines
11 KiB
Plaintext

$OpenBSD: patch-wmmon_wmmon_c,v 1.3 2002/01/06 16:54:49 naddy Exp $
--- wmmon/wmmon.c.orig Wed May 20 03:13:16 1998
+++ wmmon/wmmon.c Thu Apr 5 23:52:44 2001
@@ -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,22 @@
#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 <kvm.h>
+#include <limits.h>
+#include <nlist.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>
@@ -102,9 +118,28 @@
char *ProgName;
int stat_current = 0; /* now global */
-FILE *fp_meminfo;
-FILE *fp_stat;
-FILE *fp_loadavg;
+kvm_t *kd = NULL;
+struct nlist nlst[] = {
+#define X_CP_TIME 0
+ { "_cp_time" },
+#define X_AVERUN 1
+ { "_averunnable" },
+#define X_DISK_COUNT 2
+ { "_disk_count" },
+#define X_DISKLIST 3
+ { "_disklist" },
+#define X_KMEMBUCKETS 4
+ { "_bucket" },
+#define X_KMEMSTAT 5
+ { "_kmemstats" },
+ { 0 }
+};
+int ndrives;
+struct disklist_head disk_head;
+struct disk *dk_drivehead;
+static int pagesize;
+static int pageshift;
+char errbuf[_POSIX2_LINE_MAX];
/* functions */
void usage(void);
@@ -114,7 +149,11 @@ 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;
@@ -154,7 +193,11 @@ void main(int argc, char *argv[]) {
}
}
+ signal(SIGPIPE, exit);
+
wmmon_routine(argc, argv);
+
+ return 0;
}
/*******************************************************************************\
@@ -213,8 +256,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 +267,58 @@ 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;
+ }
+
+ /* get the page size and calculate pageshift from it */
+ pagesize = sysconf(_SC_PAGESIZE);
+ pageshift = 0;
+ while (pagesize > 1) {
+ pageshift++;
+ pagesize >>= 1;
+ }
+
+ /* we only need the amount of log(2)1024 for our conversion */
+ pageshift -= 10;
+
+ if ((kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf)) == NULL) {
+ fprintf(stderr, "kvm_openfiles: %s\n", errbuf);
+ exit(errno);
+ }
+
+ /* drop privs */
+ setegid(getgid());
+ setgid(getgid());
+
+ if (kd) {
+ if (kvm_nlist(kd, nlst) >= 0) {
+ int i;
+ for ( i = 0; nlst[i].n_name == NULL; i++)
+ if (nlst[i].n_type == 0) {
+ /* this one wasn't found */
+ (void) fprintf(stderr, "kernel: no symbol named `%s'\n", nlst[i].n_name);
+ kvm_close(kd);
+ exit(-1);
+ }
- fp = fopen("/proc/uptime", "r");
- fp_meminfo = fopen("/proc/meminfo", "r");
- fp_loadavg = fopen("/proc/loadavg", "r");
- fp_stat = fopen("/proc/stat", "r");
-
- if (fp) {
- fscanf(fp, "%ld", &online_time);
- ref_time = time(0);
- fclose(fp);
+ if (nlst[0].n_type != 0) {
+ (void) kvm_read(kd, nlst[X_DISK_COUNT].n_value, (char *)&ndrives, sizeof(ndrives));
+ if ( ndrives > 0 ) {
+ kvm_read(kd, nlst[X_DISKLIST].n_value, &disk_head, sizeof(disk_head));
+ dk_drivehead = disk_head.tqh_first;
+ }
+ }
+ } else fprintf(stderr, "kvm_nlist: %s\n", kvm_geterr(kd));
}
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,19 +326,22 @@ 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"
+ int tmpsize = strlen(p) + sizeof(RCFILE) + 1;
+ char *tmp = malloc(tmpsize);
+ if (tmp != NULL) {
+ snprintf(tmp, tmpsize, "%s" RCFILE, p);
+ parse_rcfile(tmp, wmmon_keys);
+ free(tmp);
+ }
+ }
- stat_online = checksysdevs();
+ 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);
@@ -266,7 +349,7 @@ void wmmon_routine(int argc, char **argv
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++) {
@@ -288,7 +371,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 +421,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 */
/*
@@ -403,9 +486,9 @@ void wmmon_routine(int argc, char **argv
RedrawWindowXY(xpm_X, xpm_Y);
break;
case DestroyNotify:
+ if (kd) kvm_close(kd);
XCloseDisplay(display);
exit(0);
- break;
case ButtonPress:
but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
break;
@@ -430,7 +513,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;
@@ -499,43 +581,22 @@ void update_stat_io(stat_dev *st) {
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;
- }
- }
-}
-
-void update_stat_swp(stat_dev *st) {
-
- char temp[128];
-
- 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;
- }
+ struct vmtotal total;
+ size_t size = sizeof(total);
+ static int mib[] = { CTL_VM, VM_METER };
+
+ /* get total -- systemwide main memory usage structure */
+ if ( sysctl(mib, 2, &total, &size, NULL, 0) < 0 )
+ bzero(&total, sizeof(total));
+
+ /* 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 ( !swapmode(&st2->rt_stat, &st2->rt_idle) ) {
+ st2->rt_idle = 0;
+ st2->rt_stat = 0;
}
-
}
/*******************************************************************************\
@@ -545,48 +606,41 @@ void update_stat_swp(stat_dev *st) {
void get_statistics(char *devname, long *is, long *ds, long *idle) {
int i;
- char temp[128];
- char *p;
- char *tokens = " \t\n";
- float f;
+ long averun[3];
+ long cp_time[CPUSTATES];
long maxdiskio=0;
*is = 0;
*ds = 0;
*idle = 0;
- 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 (!strncmp(devname, "cpu", 3))
+ if (kd)
+ if (kvm_nlist(kd, nlst) >= 0)
+ if (nlst[0].n_type != 0)
+ if ((kvm_read(kd, nlst[X_CP_TIME].n_value, (char *)&cp_time, sizeof(cp_time))==sizeof(cp_time)) &&
+ (kvm_read(kd, nlst[X_AVERUN].n_value, (char *)&averun, sizeof(averun))==sizeof(averun))) {
+ *is = (long) (100 * ((double)averun[0] / FSCALE));
+
+ for (i = 0; i < CPUSTATES; i++)
+ if (i != CP_IDLE) *ds += cp_time[i];
+ *idle = cp_time[CP_IDLE];
+ }
if (!strncmp(devname, "i/o", 3)) {
+ struct disk cur_disk, *p;
+
+ p = dk_drivehead;
+
+ if (kd)
+ if (kvm_nlist(kd, nlst) >= 0)
+ if (nlst[0].n_type != 0)
+ for (i = 0; i < ndrives; i++)
+ if ( kvm_read(kd, (u_long)p, &cur_disk, sizeof(cur_disk)) == sizeof(cur_disk) ) {
+ *ds += cur_disk.dk_seek;
+ p = cur_disk.dk_link.tqe_next;
+ }
- 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;
}
}
@@ -597,9 +651,9 @@ void get_statistics(char *devname, long
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;
}
@@ -736,4 +790,34 @@ void printversion(void) {
if (!strcmp(ProgName, "wmmon")) {
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;
}