//
// free.c
// a new implementaion by Darren Kirby
// copyright 2005
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#define appname "d's free"
#define appversion "0.2"
int getfree(int C, int T, int BC) {
struct meminfo {
unsigned long int memtotal;
unsigned long int memfree;
unsigned long int buffers;
unsigned long int cached;
unsigned long int swapcached;
unsigned long int active;
unsigned long int inactive;
unsigned long int hightotal;
unsigned long int highfree;
unsigned long int lowtotal;
unsigned long int lowfree;
unsigned long int swaptotal;
unsigned long int swapfree;
unsigned long int dirty;
unsigned long int writeback;
unsigned long int mapped;
unsigned long int slab;
unsigned long int commitlimit;
unsigned long int committed_as;
unsigned long int pagetables;
unsigned long int vmalloctotal;
unsigned long int mallocused;
unsigned long int mallocchunk;
};
int i;
struct meminfo minfo;
char lines[35];
char *line = lines;
char memtype[15];
long int value[23];
FILE *memi;
memi = fopen("/proc/meminfo", "r");
if (!memi) {
printf("open failed\n");
return EXIT_FAILURE;
}
for (i = 0; i < 23; i++) {
line = fgets(lines, 30, memi);
sscanf(line, "%s%d kB", &memtype, &value[i]);
}
minfo = (struct meminfo) { value[0], value[1], value[2], value[3],
value[4], value[5], value[6], value[7],
value[8], value[9], value[10], value[11],
value[12], value[13], value[14], value[15],
value[16], value[17], value[18], value[19],
value[20], value[21], value[22]};
long int memused;
long int used_minus_buffer;
long int free_plus_buffer;
int used_swap;
memused = minfo.memtotal - minfo.memfree;
used_minus_buffer = memused - (minfo.buffers + minfo.cached);
free_plus_buffer = minfo.memfree + minfo.buffers + minfo.cached;
used_swap = minfo.swaptotal - minfo.swapfree;
printf("%18s %10s %10s %10s %10s %10s\n", "total","used","free","shared","buffers", "cached");
printf("Mem:%14lu %10lu %10lu %10lu %10lu %10lu\n",
fmt(minfo.memtotal,C), fmt(memused,C), fmt(minfo.memfree,C),
// shared no longer computed...
fmt(0,C), fmt(minfo.buffers,C), fmt(minfo.cached,C));
(BC == 1) ? printf("-/+ buffers/cache: %10lu %10lu\n", fmt(used_minus_buffer,C), fmt(free_plus_buffer,C)) : printf("");
printf("Swap: %12lu %10i %10lu\n", fmt(minfo.swaptotal,C), fmt(used_swap,C), fmt(minfo.swapfree,C));
(T == 1) ? printf("Total: %11lu %10lu %10lu\n", fmt(minfo.memtotal + minfo.swaptotal,C), fmt(memused + used_swap,C),
fmt(minfo.memfree + minfo.swapfree,C)) : printf("");
return 0;
}
fmt(unsigned long n, int C) {
if (C == 2) {
return n / 1024;
} else if (C == 1) {
return n * 1024;
} else {
return n;
}
}
int showusage(void) {
printf("usage: free [-b|-k|-m] [-o] [-t] [-s delay] [-V]\n \
-b,-k,-m show output in bytes, KB, or MB\n \
-o use old format (no -/+buffers/cache line\n \
-t display total for RAM + swap\n \
-s update every [delay] seconds\n \
-V display version information and exit\n");
return EXIT_FAILURE;
}
int main(int argc, char *argv[]) {
int opt;
int C = 0; // -b, -k, or -m
int P = 0; // polling?
int T = 0; // print total?
int BC = 1; // display -/+ buffer/cache?
int poll_interval;
while ((opt = getopt(argc, argv, "bkmts:oV")) != -1) {
switch(opt) {
case 'b': C = 1; break;
case 'm': C = 2; break;
case 's': P = 1; poll_interval = atoi(optarg); break;
case 'V': printf("%s version %s\n", appname, appversion); exit(0); break;
case 't': T = 1; break;
case 'o': BC = 0; break;
default : showusage(); exit(1);
}
}
if (P == 1) {
while (1 == 1) {
getfree(C,T,BC);
printf("\n");
sleep(poll_interval);
}
} else {
getfree(C,T,BC);
return EXIT_SUCCESS;
}
}
syntax highlighted by Code2HTML, v. 0.9.1