patch-wmmon_wmmon_c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. $OpenBSD: patch-wmmon_wmmon_c,v 1.9 2014/09/17 14:37:23 espie Exp $
  2. --- wmmon/wmmon.c.orig Tue May 19 15:13:16 1998
  3. +++ wmmon/wmmon.c Wed Sep 17 08:36:25 2014
  4. @@ -28,6 +28,10 @@
  5. Changes:
  6. ----
  7. + 28/09/2000 (Vladimir Popov, pva48@mail.ru)
  8. + * Ported to OpenBSD
  9. + Based on FreeBSD port by Stephen Kiernan,
  10. + OpenBSD top and vmstat
  11. 18/05/1998 (Antoine Nulle, warp@xs4all.nl)
  12. * MEM/SWAP/UPTIME only updated when visible
  13. * Using global file descriptors to reduce file
  14. @@ -72,10 +76,22 @@
  15. #include <fcntl.h>
  16. #include <unistd.h>
  17. +#include <errno.h>
  18. +#include <signal.h>
  19. +
  20. #include <sys/wait.h>
  21. #include <sys/param.h>
  22. #include <sys/types.h>
  23. +#include <sys/proc.h>
  24. +#include <sys/disk.h>
  25. +#include <sys/sched.h>
  26. +#include <sys/malloc.h>
  27. +#include <sys/swap.h>
  28. +#include <sys/sysctl.h>
  29. +#include <sys/vmmeter.h>
  30. +#include <limits.h>
  31. +
  32. #include <X11/Xlib.h>
  33. #include <X11/xpm.h>
  34. #include <X11/extensions/shape.h>
  35. @@ -100,11 +116,11 @@
  36. /* Global Variables */
  37. /********************/
  38. -char *ProgName;
  39. int stat_current = 0; /* now global */
  40. -FILE *fp_meminfo;
  41. -FILE *fp_stat;
  42. -FILE *fp_loadavg;
  43. +int ndrives;
  44. +int pagesize;
  45. +int pageshift;
  46. +char errbuf[_POSIX2_LINE_MAX];
  47. /* functions */
  48. void usage(void);
  49. @@ -114,17 +130,15 @@ void DrawStats_io(int *, int, int, int, int);
  50. void wmmon_routine(int, char **);
  51. -void main(int argc, char *argv[]) {
  52. +/* OpenBSD specific functions */
  53. +#define pagetok(size) ((size) << pageshift)
  54. +int swapmode(long *, long *);
  55. +int main(int argc, char *argv[])
  56. +{
  57. int i;
  58. -
  59. /* Parse Command Line */
  60. -
  61. - ProgName = argv[0];
  62. - if (strlen(ProgName) >= 5)
  63. - ProgName += (strlen(ProgName) - 5);
  64. -
  65. for (i=1; i<argc; i++) {
  66. char *arg = argv[i];
  67. @@ -155,22 +169,22 @@ void main(int argc, char *argv[]) {
  68. }
  69. wmmon_routine(argc, argv);
  70. +
  71. + return 0;
  72. }
  73. -/*******************************************************************************\
  74. -|* wmmon_routine *|
  75. -\*******************************************************************************/
  76. +/***************************************************************************\
  77. +|* wmmon_routine *|
  78. +\***************************************************************************/
  79. typedef struct {
  80. -
  81. - char name[5]; /* "cpu0..cpuz", eventually.. :) */
  82. - int his[55];
  83. - int hisaddcnt;
  84. + char name[5]; /* "cpu0..cpuz", eventually.. :) */
  85. + int his[55];
  86. + int hisaddcnt;
  87. long rt_stat;
  88. long statlast;
  89. long rt_idle;
  90. long idlelast;
  91. -
  92. } stat_dev;
  93. #define MAX_STAT_DEVICES (4)
  94. @@ -182,7 +196,6 @@ char *middle_action;
  95. int checksysdevs(void);
  96. -void get_statistics(char *, long *, long *, long *);
  97. void DrawActive(char *);
  98. void update_stat_cpu(stat_dev *);
  99. @@ -213,8 +226,9 @@ void wmmon_routine(int argc, char **argv) {
  100. long istat;
  101. long idle;
  102. - FILE *fp;
  103. - char temp[128];
  104. + int mib[2];
  105. + size_t size;
  106. + struct timeval boottime;
  107. char *p;
  108. int xpm_X = 0, xpm_Y = 0;
  109. @@ -223,22 +237,36 @@ void wmmon_routine(int argc, char **argv) {
  110. long ref_time = 0;
  111. long cnt_time;
  112. + mib[0] = CTL_KERN;
  113. + mib[1] = KERN_BOOTTIME;
  114. + size = sizeof(boottime);
  115. + if ( (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) && (boottime.tv_sec != 0) ) {
  116. + ref_time = time(NULL);
  117. + online_time = ref_time - boottime.tv_sec + 30;
  118. + }
  119. - fp = fopen("/proc/uptime", "r");
  120. - fp_meminfo = fopen("/proc/meminfo", "r");
  121. - fp_loadavg = fopen("/proc/loadavg", "r");
  122. - fp_stat = fopen("/proc/stat", "r");
  123. + /* get the page size and calculate pageshift from it */
  124. + pagesize = sysconf(_SC_PAGESIZE);
  125. + pageshift = 0;
  126. + while (pagesize > 1) {
  127. + pageshift++;
  128. + pagesize >>= 1;
  129. + }
  130. - if (fp) {
  131. - fscanf(fp, "%ld", &online_time);
  132. - ref_time = time(0);
  133. - fclose(fp);
  134. + /* we only need the amount of log(2)1024 for our conversion */
  135. + pageshift -= 10;
  136. +
  137. + mib[0] = CTL_HW;
  138. + mib[1] = HW_DISKCOUNT;
  139. + size = sizeof(ndrives);
  140. + if (sysctl(mib, 2, &ndrives, &size, NULL, 0) < 0 ) {
  141. + warn("could not read hw.diskcount");
  142. + ndrives = 0;
  143. }
  144. for (i=0; i<MAX_STAT_DEVICES; i++) {
  145. - for (j=0; j<55; j++) {
  146. + for (j=0; j<55; j++)
  147. stat_device[i].his[j] = 0;
  148. - }
  149. stat_device[i].hisaddcnt = 0;
  150. }
  151. @@ -246,38 +274,40 @@ void wmmon_routine(int argc, char **argv) {
  152. if (RIGHT_ACTION) right_action = strdup(RIGHT_ACTION);
  153. if (MIDDLE_ACTION) middle_action = strdup(MIDDLE_ACTION);
  154. - strcpy(temp, "/etc/wmmonrc");
  155. - parse_rcfile(temp, wmmon_keys);
  156. + parse_rcfile("/etc/wmmonrc", wmmon_keys);
  157. - p = getenv("HOME");
  158. - strcpy(temp, p);
  159. - strcat(temp, "/.wmmonrc");
  160. - parse_rcfile(temp, wmmon_keys);
  161. -
  162. - strcpy(temp, "/etc/wmmonrc.fixed");
  163. - parse_rcfile(temp, wmmon_keys);
  164. + if ((p = getenv("HOME")) != NULL) {
  165. +#define RCFILE "/.wmmonrc"
  166. + char *tmp;
  167. - stat_online = checksysdevs();
  168. + if (asprintf(&tmp, "%s" RCFILE, p) != -1) {
  169. + parse_rcfile(tmp, wmmon_keys);
  170. + free(tmp);
  171. + }
  172. + }
  173. + parse_rcfile("/etc/wmmonrc.fixed", wmmon_keys);
  174. + stat_online = checksysdevs();
  175. +
  176. openXwindow(argc, argv, wmmon_master_xpm, wmmon_mask_bits, wmmon_mask_width, wmmon_mask_height);
  177. /* add mouse region */
  178. AddMouseRegion(0, 12, 13, 58, 57);
  179. AddMouseRegion(1, 5, 5, 24, 14);
  180. - starttime = time(0);
  181. + starttime = time(NULL);
  182. nexttime = starttime + 10;
  183. for (i=0; i<stat_online; i++) {
  184. - get_statistics(stat_device[i].name, &k, &istat, &idle);
  185. - stat_device[i].statlast = istat;
  186. - stat_device[i].idlelast = idle;
  187. + stat_device[i].statlast = 0;
  188. + stat_device[i].idlelast = 0;
  189. }
  190. - if (stat_current == 0) DrawStats(stat_device[stat_current].his, 54, 40, 5, 58);
  191. - if (stat_current == 1) {
  192. + if (stat_current == 0)
  193. + DrawStats(stat_device[stat_current].his, 54, 40, 5, 58);
  194. + if (stat_current == 1)
  195. DrawStats_io(stat_device[stat_current].his, 54, 40, 5, 58);
  196. - }
  197. +
  198. if (stat_current == 2) {
  199. xpm_X = 64;
  200. setMaskXY(-64, 0);
  201. @@ -288,7 +318,7 @@ void wmmon_routine(int argc, char **argv) {
  202. DrawActive(stat_device[stat_current].name);
  203. while (1) {
  204. - curtime = time(0);
  205. + curtime = time(NULL);
  206. waitpid(0, NULL, WNOHANG);
  207. @@ -338,7 +368,7 @@ void wmmon_routine(int argc, char **argv) {
  208. /*----------- online tijd neerzetten! ----------*/
  209. - cnt_time = time(0) - ref_time + online_time;
  210. + cnt_time = time(NULL) - ref_time + online_time;
  211. /* cnt_time = uptime in seconden */
  212. /*
  213. @@ -405,7 +435,6 @@ void wmmon_routine(int argc, char **argv) {
  214. case DestroyNotify:
  215. XCloseDisplay(display);
  216. exit(0);
  217. - break;
  218. case ButtonPress:
  219. but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
  220. break;
  221. @@ -430,7 +459,6 @@ void wmmon_routine(int argc, char **argv) {
  222. }
  223. case 1:
  224. stat_current++;
  225. - printf("current stat is :%d\n", stat_current);
  226. if (stat_current == stat_online)
  227. stat_current = 0;
  228. @@ -460,146 +488,116 @@ void wmmon_routine(int argc, char **argv) {
  229. void update_stat_cpu(stat_dev *st) {
  230. - long k, istat, idle;
  231. + static int sysload_mib[] = {CTL_VM, VM_LOADAVG};
  232. + static int cp_time_mib[] = {CTL_KERN, KERN_CPTIME};
  233. + struct loadavg sysload;
  234. + double infoload;
  235. + size_t size;
  236. + long cp_time[CPUSTATES];
  237. + long istat, idle;
  238. + int i;
  239. - get_statistics(st->name, &k, &istat, &idle);
  240. + /* mostly stolen from src/usr.bin/top/machine.c */
  241. + size = sizeof(cp_time);
  242. + if (sysctl(cp_time_mib, 2, &cp_time, &size, NULL, 0) < 0)
  243. + warn("sysctl kern.cp_time failed");
  244. + size = sizeof(sysload);
  245. + if (sysctl(sysload_mib, 2, &sysload, &size, NULL, 0) < 0)
  246. + warn("sysctl failed");
  247. + infoload = ((double) sysload.ldavg[0]) / sysload.fscale;
  248. +
  249. + for (i = 0, istat = 0; i < CPUSTATES; i++)
  250. + if (i != CP_IDLE) istat += cp_time[i];
  251. + idle = cp_time[CP_IDLE];
  252. +
  253. st->rt_idle = idle - st->idlelast;
  254. st->idlelast = idle;
  255. st->rt_stat = istat - st->statlast;
  256. st->statlast = istat;
  257. - st->his[54] += k;
  258. + st->his[54] += (long)(100 * infoload);
  259. st->hisaddcnt += 1;
  260. }
  261. void update_stat_io(stat_dev *st) {
  262. - long j, k, istat, idle;
  263. - static long maxdiskio = 0;
  264. + struct diskstats *q;
  265. + static int io_mib[] = {CTL_HW, HW_DISKSTATS};
  266. + int mib[] = {CTL_HW, HW_DISKCOUNT};
  267. + static long maxdiskxfers = 0;
  268. + long xfers, rwstat;
  269. + size_t size;
  270. + int i;
  271. - get_statistics(st->name, &k, &istat, &idle);
  272. + size = sizeof(ndrives);
  273. + if (sysctl(mib, 2, &ndrives, &size, NULL, 0) < 0 ) {
  274. + warn("could not read hw.diskcount");
  275. + return;
  276. + }
  277. - st->rt_idle = idle - st->idlelast;
  278. - st->idlelast = idle;
  279. -
  280. - st->rt_stat = istat - st->statlast;
  281. - st->statlast = istat;
  282. -
  283. - j = st->rt_stat;
  284. - if (maxdiskio < j) {
  285. - maxdiskio = j;
  286. + size = ndrives * sizeof(struct diskstats);
  287. + q = malloc(size);
  288. + if (q == NULL)
  289. + err(1, NULL);
  290. + if (sysctl(io_mib, 2, q, &size, NULL, 0) < 0) {
  291. + warn("could not read hw.diskstats");
  292. + bzero(q, ndrives * sizeof(struct diskstats));
  293. }
  294. - st->rt_idle = maxdiskio - j;
  295. - st->his[54] += st->rt_stat;
  296. - st->hisaddcnt += 1;
  297. -}
  298. -
  299. -void update_stat_mem(stat_dev *st, stat_dev *st2) {
  300. -
  301. - char temp[128];
  302. - unsigned long free, shared, buffers, cached;
  303. -
  304. - freopen("/proc/meminfo", "r", fp_meminfo);
  305. - while (fgets(temp, 128, fp_meminfo)) {
  306. - if (strstr(temp, "Mem:")) {
  307. - sscanf(temp, "Mem: %ld %ld %ld %ld %ld %ld",
  308. - &st->rt_idle, &st->rt_stat,
  309. - &free, &shared, &buffers, &cached);
  310. - st->rt_idle >>= 10;
  311. - st->rt_stat -= buffers+cached;
  312. - st->rt_stat >>= 10;
  313. -// break;
  314. - }
  315. - if (strstr(temp, "Swap:")) {
  316. - sscanf(temp, "Swap: %ld %ld", &st2->rt_idle, &st2->rt_stat);
  317. - st2->rt_idle >>= 10;
  318. - st2->rt_stat >>= 10;
  319. - break;
  320. - }
  321. + for (i = 0; i < ndrives; i++) {
  322. + rwstat += q[i].ds_rbytes + q[i].ds_wbytes;
  323. + xfers += q[i].ds_rxfer + q[i].ds_wxfer;
  324. }
  325. -}
  326. + free(q);
  327. +
  328. + if (st->statlast == 0)
  329. + st->statlast = xfers;
  330. + if (xfers < st->statlast)
  331. + xfers = st->statlast;
  332. + st->rt_stat = xfers - st->statlast;
  333. + st->statlast = xfers;
  334. -void update_stat_swp(stat_dev *st) {
  335. + if (maxdiskxfers < st->rt_stat)
  336. + maxdiskxfers = st->rt_stat;
  337. - char temp[128];
  338. + st->rt_idle = maxdiskxfers - st->rt_stat;
  339. + st->idlelast = 0;
  340. - fseek(fp_meminfo, 0, SEEK_SET);
  341. - while (fgets(temp, 128, fp_meminfo)) {
  342. - if (strstr(temp, "Swap:")) {
  343. - sscanf(temp, "Swap: %ld %ld", &st->rt_idle, &st->rt_stat);
  344. - st->rt_idle >>= 10;
  345. - st->rt_stat >>= 10;
  346. - break;
  347. - }
  348. - }
  349. -
  350. + st->his[54] += rwstat;
  351. + st->hisaddcnt += 1;
  352. }
  353. -/*******************************************************************************\
  354. -|* get_statistics *|
  355. -\*******************************************************************************/
  356. +void update_stat_mem(stat_dev *st, stat_dev *st2) {
  357. -void get_statistics(char *devname, long *is, long *ds, long *idle) {
  358. + struct vmtotal total;
  359. + size_t size = sizeof(total);
  360. + static int mib[] = { CTL_VM, VM_METER };
  361. - int i;
  362. - char temp[128];
  363. - char *p;
  364. - char *tokens = " \t\n";
  365. - float f;
  366. - long maxdiskio=0;
  367. + /* get total -- systemwide main memory usage structure */
  368. + if ( sysctl(mib, 2, &total, &size, NULL, 0) < 0 )
  369. + bzero(&total, sizeof(total));
  370. - *is = 0;
  371. - *ds = 0;
  372. - *idle = 0;
  373. + /* FIXME: is it right to count memory like this */
  374. + st->rt_idle = pagetok(total.t_rm + total.t_free);
  375. + st->rt_stat = pagetok(total.t_rm);
  376. - if (!strncmp(devname, "cpu", 3)) {
  377. - fseek(fp_stat, 0, SEEK_SET);
  378. - while (fgets(temp, 128, fp_stat)) {
  379. - if (strstr(temp, "cpu")) {
  380. - p = strtok(temp, tokens);
  381. - /* 1..3, 4 == idle, we don't want idle! */
  382. - for (i=0; i<3; i++) {
  383. - p = strtok(NULL, tokens);
  384. - *ds += atol(p);
  385. - }
  386. - p = strtok(NULL, tokens);
  387. - *idle = atol(p);
  388. - }
  389. - }
  390. - fp_loadavg = freopen("/proc/loadavg", "r", fp_loadavg);
  391. - fscanf(fp_loadavg, "%f", &f);
  392. - *is = (long) (100 * f);
  393. + if ( !swapmode(&st2->rt_stat, &st2->rt_idle) ) {
  394. + st2->rt_idle = 0;
  395. + st2->rt_stat = 0;
  396. }
  397. -
  398. - if (!strncmp(devname, "i/o", 3)) {
  399. -
  400. - fseek(fp_stat, 0, SEEK_SET);
  401. - while (fgets(temp, 128, fp_stat)) {
  402. - if (strstr(temp, "disk_rio") || strstr(temp, "disk_wio")) {
  403. - p = strtok(temp, tokens);
  404. - /* 1..4 */
  405. - for (i=0; i<4; i++) {
  406. - p = strtok(NULL, tokens);
  407. - *ds += atol(p);
  408. - }
  409. - }
  410. - }
  411. - if (*ds > maxdiskio) maxdiskio = *ds;
  412. - }
  413. }
  414. -/*******************************************************************************\
  415. -|* checksysdevs *|
  416. -\*******************************************************************************/
  417. +/***************************************************************************\
  418. +|* checksysdevs *|
  419. +\***************************************************************************/
  420. int checksysdevs(void) {
  421. - strcpy(stat_device[0].name, "cpu0");
  422. - strcpy(stat_device[1].name, "i/o");
  423. - strcpy(stat_device[2].name, "sys");
  424. + strncpy(stat_device[0].name, "cpu0", 5);
  425. + strncpy(stat_device[1].name, "i/o", 5);
  426. + strncpy(stat_device[2].name, "sys", 5);
  427. return 3;
  428. }
  429. @@ -733,7 +731,35 @@ void usage(void) {
  430. void printversion(void) {
  431. - if (!strcmp(ProgName, "wmmon")) {
  432. - fprintf(stderr, "%s\n", WMMON_VERSION);
  433. - }
  434. + fprintf(stderr, "%s\n", WMMON_VERSION);
  435. +}
  436. +
  437. +int swapmode(long *used, long *total) {
  438. + int nswap, rnswap, i;
  439. + struct swapent *swdev;
  440. +
  441. + nswap = swapctl(SWAP_NSWAP, 0, 0);
  442. + if (nswap == 0)
  443. + return 0;
  444. +
  445. + swdev = malloc(nswap * sizeof(*swdev));
  446. + if(swdev == NULL)
  447. + return 0;
  448. +
  449. + rnswap = swapctl(SWAP_STATS, swdev, nswap);
  450. + if(rnswap == -1)
  451. + return 0;
  452. +
  453. + /* if rnswap != nswap, then what? */
  454. +
  455. + /* Total things up */
  456. + *total = *used = 0;
  457. + for (i = 0; i < nswap; i++)
  458. + if (swdev[i].se_flags & SWF_ENABLE) {
  459. + *used += (swdev[i].se_inuse / (1024/DEV_BSIZE));
  460. + *total += (swdev[i].se_nblks / (1024/DEV_BSIZE));
  461. + }
  462. +
  463. + free (swdev);
  464. + return 1;
  465. }