2 * mem_linux.c - module to get memory/swap usages, for GNU/Linxu
4 * Copyright(C) 2001,2002 Seiichi SATO <ssato@sh.rim.or.jp>
5 * Copyright(C) 2001 John McCutchan <ttb@tentacle.dhs.org>
7 * licensed under the GPL
18 #if defined(HAVE_STRING_H)
20 #elif defined(HAVE_STRINGS_H)
24 #include <sys/types.h>
28 #include <sys/utsname.h>
33 BETWEEN_2_5_1_AND_3_14
,
38 # define INLINE_STATIC static
40 # define INLINE_STATIC static inline
43 /* initialize function */
47 int version
, patchlevel
, sublevel
;
49 /* get kernel version */
52 sscanf(un
.release
, "%d.%d.%d", &version
, &patchlevel
, &sublevel
);
54 /* new format ? (kernel >= 3.14 or 2.5.1pre?) */
55 /* see linux/fs/proc/proc_misc.c */
56 /* or linux/fs/proc/meminfo.c */
57 if ((version
== 3 && patchlevel
>= 14) || version
> 3)
59 else if ((version
== 2 && patchlevel
>= 5 && sublevel
>= 1) ||
60 (version
== 2 && patchlevel
>= 6 && sublevel
>= 0) ||
62 format
= BETWEEN_2_5_1_AND_3_14
;
64 format
= BEFORE_2_5_1
;
68 INLINE_STATIC
char *skip_line(const char *p
)
75 INLINE_STATIC
char *skip_token(const char *p
)
79 while (*p
&& !isspace(*p
))
84 INLINE_STATIC
char *skip_multiple_token(const char *p
, int count
)
87 for (i
= 0; i
< count
; i
++)
92 /* return mem/swap usage in percent 0 to 100 */
93 void mem_getusage(int *per_mem
, int *per_swap
, const struct mem_options
*opts
)
95 char buffer
[BUFSIZ
], *p
;
97 u_int64_t mtotal
, mused
, mfree
, mbuffer
, mcached
, mavail
;
98 u_int64_t stotal
, sused
, sfree
, scached
= 0;
100 /* read /proc/meminfo */
101 fd
= open("/proc/meminfo", O_RDONLY
);
103 perror("can't open /proc/meminfo");
106 len
= read(fd
, buffer
, BUFSIZ
- 1);
108 perror("can't read /proc/meminfo");
119 for (i
= 0; i
< 3; i
++)
122 /* examine each line of file */
123 mtotal
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
124 mfree
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 5);
125 mbuffer
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
126 mcached
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
127 scached
= strtoul(p
, &p
, 0);
130 case (BETWEEN_2_5_1_AND_3_14
):
132 /* examine each line of file */
133 mtotal
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
134 mfree
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
135 mbuffer
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
136 mcached
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
137 scached
= strtoul(p
, &p
, 0);
142 /* examine each line of file */
143 mtotal
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
144 mfree
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
145 mavail
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
146 mbuffer
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
147 mcached
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
148 scached
= strtoul(p
, &p
, 0);
153 /* skip N lines and examine info about swap */
154 /* kernel-2.4.2:N=8 2.4.16:N=7 */
155 while (isprint(p
[0])) {
157 if (strncmp(p
, "SwapTotal", 9) == 0)
162 stotal
= strtoul(p
, &p
, 0); p
= skip_multiple_token(p
, 2);
163 sfree
= strtoul(p
, &p
, 0);
165 if (format
== AFTER_3_14
) {
166 *per_mem
= 100 * (double) (mtotal
- mavail
) / (double) mtotal
;
168 /* calculate memory usage in percent */
169 mused
= mtotal
- mfree
;
170 if (opts
->ignore_buffers
)
172 if (opts
->ignore_cached
)
174 *per_mem
= 100 * (double) mused
/ (double) mtotal
;
177 /* calculate swap usage in percent */
178 sused
= stotal
- sfree
;
179 if (opts
->ignore_cached
)
184 *per_swap
= 100 * (double) sused
/ (double) stotal
;
187 printf("-----------------------\n");
188 printf("MemTotal: %12ld\n", (unsigned long)mtotal
);
189 printf("MemFree: %12ld\n", (unsigned long)mfree
);
190 printf("Buffers: %12ld\n", (unsigned long)mbuffer
);
191 printf("Cached: %12ld\n", (unsigned long)mcached
);
192 printf("SwapTotal: %12ld\n", (unsigned long)stotal
);
193 printf("SwapFree: %12ld\n", (unsigned long)sfree
);
194 printf("SwapCached:%12ld\n", (unsigned long)scached
);
195 printf("-----------------------\n\n");