#include <stdio.h>
#define KIBIBYTE_SIZE 1024LL
#define MEBIBYTE_SIZE 1048576LL
#define GIBIBYTE_SIZE 1073741824LL
#define TEBIBYTE_SIZE 1099511627776LL
typedef enum {
DIGIT_UNIT_BYTE,
DIGIT_UNIT_KIBIBYTE,
DIGIT_UNIT_MEBIBYTE,
DIGIT_UNIT_GIBIBYTE,
DIGIT_UNIT_TEBIBYTE
} DigitUnit;
static char*
find_suffix (const char* str)
{
while (str[0] != 0 && (isdigit (str[0]) || strchr(",.-", str[0]) || isspace (str[0])))
str++;
return (char *) str;
}
static char*
find_digit (const char* str)
{
while (str[0] != 0 && (!isdigit (str[0])))
str++;
return (char *) str;
}
static DigitUnit
parse_unit_suffix (const char* suffix)
{
if (strlen (suffix) > 0) {
switch (tolower (suffix[0])) {
case 'b': return DIGIT_UNIT_BYTE;
case 'k': return DIGIT_UNIT_KIBIBYTE;
case 'm': return DIGIT_UNIT_MEBIBYTE;
case 'g': return DIGIT_UNIT_GIBIBYTE;
case 't': return DIGIT_UNIT_TEBIBYTE;
}
}
return -1;
}
long long unit_size (DigitUnit unit)
{
switch (unit) {
case DIGIT_UNIT_BYTE:
return 1;
case DIGIT_UNIT_KIBIBYTE:
return KIBIBYTE_SIZE;
case DIGIT_UNIT_MEBIBYTE:
return MEBIBYTE_SIZE;
case DIGIT_UNIT_GIBIBYTE:
return GIBIBYTE_SIZE;
case DIGIT_UNIT_TEBIBYTE:
return TEBIBYTE_SIZE;
}
}
typedef struct {
long long total;
long long used;
} MemInfo;
int
meminfo (MemInfo *meminfo)
{
char line[128];
FILE* fp;
long long totalmem;
long long usedmem;
char *digit;
char *suffix;
totalmem = 0;
usedmem = 0;
digit = 0;
suffix = 0;
memset (line, 0, 128);
fp = fopen ("/proc/meminfo", "rb");
if (fp < 0) {
return -1;
}
fgets (line, 128, fp);
digit = find_digit (line);
suffix = find_suffix (digit);
if (sscanf (digit, "%d", &totalmem) == 1) {
meminfo->total = totalmem * unit_size(parse_unit_suffix(suffix));
}
fgets (line, 128, fp);
digit = find_digit (line);
suffix = find_suffix (digit);
if (sscanf (digit, "%d", &usedmem) == 1) {
meminfo->used = usedmem * unit_size(parse_unit_suffix(suffix));
}
return 0;
}
int main()
{
MemInfo mem;
meminfo (&mem);
printf ("total:%lld used:%lld\n", mem.total, mem.used);
return 0;
}