[tpwd] Fix segfault when exactly one argument given
[tinyapps.git] / load.c
blob7fca5b9ef00d5e9673ff46a40984f40e41dbb46a
1 /*
2 * Shows CPU load and some other information.
3 * Copyright (c) 2005,2007 by Michal Nazareicz <mina86@mina86.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * This is part of Tiny Applications Collection
19 * -> http://tinyapps.sourceforge.net/
23 #include <limits.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
29 /**** Defines ****/
30 #define BUFFER_SIZE 1024
31 static char buffer[BUFFER_SIZE];
34 #ifdef ULLONG_MAX
35 typedef unsigned long long bigint;
36 #define FMT "llu"
37 #else
38 typedef unsigned long bigint;
39 #define FMT "lu"
40 #endif
43 /**** Structire with all information ****/
44 typedef struct {
45 struct {
46 bigint usr, nice, sys, idle, load, total;
47 } cpu;
48 struct {
49 bigint rec, send;
50 } traf;
51 struct {
52 unsigned long total, free;
53 } mem;
54 } State;
57 /**** Updates CPU load info ****/
58 static void update_cpu(State *state) {
59 FILE *file = fopen("/proc/stat", "r");
60 int i;
61 if (!file) return;
63 i = fscanf(file, "%*s %" FMT " %" FMT " %" FMT " %" FMT ,
64 &state->cpu.usr, &state->cpu.nice,
65 &state->cpu.sys, &state->cpu.idle);
66 fclose(file);
68 switch (i) {
69 case 0:
70 state->cpu.usr = 0;
71 case 1:
72 state->cpu.nice = 0;
73 case 2:
74 state->cpu.sys = 0;
75 case 3:
76 state->cpu.idle = 0;
79 state->cpu.load = state->cpu.usr + state->cpu.sys + state->cpu.nice;
80 state->cpu.total = state->cpu.load + state->cpu.idle;
84 /**** Updates traffic info ****/
85 static void update_traf(State *state) {
86 FILE *file = fopen("/proc/net/dev", "r");
87 if (!file) return;
89 while (fgets(buffer, BUFFER_SIZE, file)) {
90 if (sscanf(buffer, " eth0:%" FMT " %*d %*d %*d %*d %*d %*d %*d %" FMT,
91 &state->traf.rec, &state->traf.send)) {
92 break;
95 fclose(file);
99 /**** Updates memory info ****/
100 static void update_mem(State *state) {
101 FILE *file = fopen("/proc/meminfo", "r");
102 unsigned long val;
103 int flags = 0;
104 if (!file) return;
106 while (fgets(buffer, BUFFER_SIZE, file) && flags!=3) {
107 if (sscanf(buffer, " MemTotal: %lu", &val)==1) {;
108 flags |= 1;
109 state->mem.total = val;
110 } else if (sscanf(buffer, " MemFree: %lu", &val)==1) {;
111 flags |= 2;
112 state->mem.free = val;
115 fclose(file);
119 /**** Calculates delta between two states ****/
120 static void make_delta(State *delta, const State *prev, const State *now) {
121 delta->cpu.usr = now->cpu.usr - prev->cpu.usr ;
122 delta->cpu.nice = now->cpu.nice - prev->cpu.nice ;
123 delta->cpu.sys = now->cpu.sys - prev->cpu.sys ;
124 delta->cpu.idle = now->cpu.idle - prev->cpu.idle ;
125 delta->cpu.load = now->cpu.load - prev->cpu.load ;
126 delta->cpu.total = now->cpu.total - prev->cpu.total;
127 delta->traf.rec = now->traf.rec - prev->traf.rec ;
128 delta->traf.send = now->traf.send - prev->traf.send;
129 delta->mem.total = now->mem.total;
130 delta->mem.free = now->mem.free ;
134 /**** Prints state ****/
135 static void print_state(const State *s) {
136 printf("%4" FMT " %4" FMT " %4" FMT " %4" FMT " %4" FMT " %4" FMT
137 " %3d%% %7ld %7ld %7" FMT " %7" FMT "\n",
138 s->cpu.usr, s->cpu.nice, s->cpu.sys, s->cpu.idle,
139 s->cpu.load, s->cpu.total,
140 (int)(s->cpu.total ? 100 * s->cpu.load / s->cpu.total : 0),
141 s->mem.free, s->mem.total,
142 s->traf.rec, s->traf.send);
146 /**** Main ****/
147 int main(void) {
148 State states[3];
149 int num = 0;
150 update_cpu(states + 1);
151 update_traf(states + 1);
152 update_mem(states + 1);
154 puts("user nice sys idle | load ttl | cpu | memfree mem-ttl "
155 "| rec send");
156 for(;;) {
157 sleep(1);
159 update_cpu(states + num);
160 update_traf(states + num);
161 update_mem(states + num);
163 make_delta(states + 2, states + (num^1), states + num);
164 print_state(states + 2);
165 num ^= 1;