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
;
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);
145 p
= skip_multiple_token(p
, 5); /* skip MemAvailable line */
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 /* calculate memory usage in percent */
166 mused
= mtotal
- mfree
;
167 if (opts
->ignore_buffers
)
169 if (opts
->ignore_cached
)
171 *per_mem
= 100 * (double) mused
/ (double) mtotal
;
173 /* calculate swap usage in percent */
174 sused
= stotal
- sfree
;
175 if (opts
->ignore_cached
)
180 *per_swap
= 100 * (double) sused
/ (double) stotal
;
183 printf("-----------------------\n");
184 printf("MemTotal: %12ld\n", (unsigned long)mtotal
);
185 printf("MemFree: %12ld\n", (unsigned long)mfree
);
186 printf("Buffers: %12ld\n", (unsigned long)mbuffer
);
187 printf("Cached: %12ld\n", (unsigned long)mcached
);
188 printf("SwapTotal: %12ld\n", (unsigned long)stotal
);
189 printf("SwapFree: %12ld\n", (unsigned long)sfree
);
190 printf("SwapCached:%12ld\n", (unsigned long)scached
);
191 printf("-----------------------\n\n");