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 }