coreutils

custom mini coreutils
git clone git://git.evenfri.xyz/coreutils.git
Log | Files | Refs | README

free.c (2715B)


      1 #include <libc.h>
      2 
      3 #define buf_size 2048
      4 
      5 static int str_starts_with(const char *str, const char *prefix) {
      6   while (*prefix) {
      7     if (*str++ != *prefix++) return 0;
      8   }
      9   return 1;
     10 }
     11 
     12 static unsigned long parse_key(const char *buf, const char *key) {
     13   int key_len = strlen(key);
     14   for (int i = 0; buf[i] != '\0'; i++) {
     15     if (str_starts_with(&buf[i], key)) {
     16       i += key_len;
     17       while (buf[i] == ' ' || buf[i] == '\t') i++;
     18       
     19       unsigned long val = 0;
     20       while (buf[i] >= '0' && buf[i] <= '9') {
     21         val = val * 10 + (buf[i] - '0');
     22         i++;
     23       }
     24       return val;
     25     }
     26   }
     27   return 0;
     28 }
     29 
     30 static void print_str(const char *s) {
     31   write(stdout, s, strlen(s));
     32 }
     33 
     34 static void print_num_padded(unsigned long val, int width) {
     35   char buf[32];
     36   int pos = 0;
     37 
     38   if (val == 0) {
     39     buf[pos++] = '0';
     40   } else {
     41     char temp[32];
     42     int tpos = 0;
     43     while (val > 0) {
     44       temp[tpos++] = '0' + (val % 10);
     45       val /= 10;
     46     }
     47     while (tpos > 0) {
     48       buf[pos++] = temp[--tpos];
     49     }
     50   }
     51   buf[pos] = '\0';
     52 
     53   int spaces = width - pos;
     54   while (spaces-- > 0) {
     55     write(stdout, " ", 1);
     56   }
     57   write(stdout, buf, pos);
     58 }
     59 
     60 int main(void) {
     61   int fd = open("/proc/meminfo", o_rdonly, 0);
     62   if (fd < 0) {
     63     write(stderr, "free: cannot open /proc/meminfo\n", 32);
     64     return 1;
     65   }
     66 
     67   char buf[buf_size];
     68   ssize_t n = read(fd, buf, sizeof(buf) - 1);
     69   close(fd);
     70 
     71   if (n <= 0) {
     72     write(stderr, "free: failed to read /proc/meminfo\n", 35);
     73     return 1;
     74   }
     75   buf[n] = '\0';
     76 
     77   unsigned long mem_total  = parse_key(buf, "MemTotal:");
     78   unsigned long mem_free   = parse_key(buf, "MemFree:");
     79   unsigned long mem_avail  = parse_key(buf, "MemAvailable:");
     80   unsigned long buffers    = parse_key(buf, "Buffers:");
     81   unsigned long cached     = parse_key(buf, "Cached:");
     82   unsigned long swap_total = parse_key(buf, "SwapTotal:");
     83   unsigned long swap_free  = parse_key(buf, "SwapFree:");
     84 
     85   unsigned long buff_cache = buffers + cached;
     86   
     87   unsigned long mem_used = 0;
     88   if (mem_total > (mem_free + buff_cache)) {
     89     mem_used = mem_total - mem_free - buff_cache;
     90   }
     91   
     92   unsigned long swap_used = (swap_total > swap_free) ? (swap_total - swap_free) : 0;
     93 
     94   print_str("               total        used        free      shared  buff/cache   available\n");
     95 
     96   print_str("Mem:   ");
     97   print_num_padded(mem_total, 12);
     98   print_num_padded(mem_used, 12);
     99   print_num_padded(mem_free, 12);
    100   print_num_padded(0, 12); /* shared */
    101   print_num_padded(buff_cache, 12);
    102   print_num_padded(mem_avail, 12);
    103   print_str("\n");
    104 
    105   print_str("Swap:  ");
    106   print_num_padded(swap_total, 12);
    107   print_num_padded(swap_used, 12);
    108   print_num_padded(swap_free, 12);
    109   print_str("\n");
    110 
    111   return 0;
    112 }