swap.c - slstatus - status monitor
git clone git://git.suckless.org/slstatus
Log
Files
Refs
README
LICENSE
---
swap.c (5044B)
---
     1 /* See LICENSE file for copyright and license details. */
     2 #include 
     3 #include 
     4 #include 
     5 #include 
     6 
     7 #include "../slstatus.h"
     8 #include "../util.h"
     9 
    10 #if defined(__linux__)
    11         static int
    12         get_swap_info(long *s_total, long *s_free, long *s_cached)
    13         {
    14                 FILE *fp;
    15                 struct {
    16                         const char *name;
    17                         const size_t len;
    18                         long *var;
    19                 } ent[] = {
    20                         { "SwapTotal",  sizeof("SwapTotal") - 1,  s_total  },
    21                         { "SwapFree",   sizeof("SwapFree") - 1,   s_free   },
    22                         { "SwapCached", sizeof("SwapCached") - 1, s_cached },
    23                 };
    24                 size_t line_len = 0, i, left;
    25                 char *line = NULL;
    26 
    27                 /* get number of fields we want to extract */
    28                 for (i = 0, left = 0; i < LEN(ent); i++)
    29                         if (ent[i].var)
    30                                 left++;
    31 
    32                 if (!(fp = fopen("/proc/meminfo", "r"))) {
    33                         warn("fopen '/proc/meminfo':");
    34                         return 1;
    35                 }
    36 
    37                 /* read file line by line and extract field information */
    38                 while (left > 0 && getline(&line, &line_len, fp) >= 0) {
    39                         for (i = 0; i < LEN(ent); i++) {
    40                                 if (ent[i].var &&
    41                                     !strncmp(line, ent[i].name, ent[i].len)) {
    42                                         sscanf(line + ent[i].len + 1,
    43                                                "%ld kB\n", ent[i].var);
    44                                         left--;
    45                                         break;
    46                                 }
    47                         }
    48                 }
    49                 free(line);
    50                 if (ferror(fp)) {
    51                         warn("getline '/proc/meminfo':");
    52                         return 1;
    53                 }
    54 
    55                 fclose(fp);
    56                 return 0;
    57         }
    58 
    59         const char *
    60         swap_free(const char *unused)
    61         {
    62                 long free;
    63 
    64                 if (get_swap_info(NULL, &free, NULL))
    65                         return NULL;
    66 
    67                 return fmt_human(free * 1024, 1024);
    68         }
    69 
    70         const char *
    71         swap_perc(const char *unused)
    72         {
    73                 long total, free, cached;
    74 
    75                 if (get_swap_info(&total, &free, &cached) || total == 0)
    76                         return NULL;
    77 
    78                 return bprintf("%d", 100 * (total - free - cached) / total);
    79         }
    80 
    81         const char *
    82         swap_total(const char *unused)
    83         {
    84                 long total;
    85 
    86                 if (get_swap_info(&total, NULL, NULL))
    87                         return NULL;
    88 
    89                 return fmt_human(total * 1024, 1024);
    90         }
    91 
    92         const char *
    93         swap_used(const char *unused)
    94         {
    95                 long total, free, cached;
    96 
    97                 if (get_swap_info(&total, &free, &cached))
    98                         return NULL;
    99 
   100                 return fmt_human((total - free - cached) * 1024, 1024);
   101         }
   102 #elif defined(__OpenBSD__)
   103         #include 
   104         #include 
   105         #include 
   106         #include 
   107 
   108         static int
   109         getstats(int *total, int *used)
   110         {
   111                 struct swapent *sep, *fsep;
   112                 int rnswap, nswap, i;
   113 
   114                 if ((nswap = swapctl(SWAP_NSWAP, 0, 0)) < 1) {
   115                         warn("swaptctl 'SWAP_NSWAP':");
   116                         return 1;
   117                 }
   118                 if (!(fsep = sep = calloc(nswap, sizeof(*sep)))) {
   119                         warn("calloc 'nswap':");
   120                         return 1;
   121                 }
   122                 if ((rnswap = swapctl(SWAP_STATS, (void *)sep, nswap)) < 0) {
   123                         warn("swapctl 'SWAP_STATA':");
   124                         return 1;
   125                 }
   126                 if (nswap != rnswap) {
   127                         warn("getstats: SWAP_STATS != SWAP_NSWAP");
   128                         return 1;
   129                 }
   130 
   131                 *total = 0;
   132                 *used = 0;
   133 
   134                 for (i = 0; i < rnswap; i++) {
   135                         *total += sep->se_nblks >> 1;
   136                         *used += sep->se_inuse >> 1;
   137                 }
   138 
   139                 free(fsep);
   140 
   141                 return 0;
   142         }
   143 
   144         const char *
   145         swap_free(const char *unused)
   146         {
   147                 int total, used;
   148 
   149                 if (getstats(&total, &used))
   150                         return NULL;
   151 
   152                 return fmt_human((total - used) * 1024, 1024);
   153         }
   154 
   155         const char *
   156         swap_perc(const char *unused)
   157         {
   158                 int total, used;
   159 
   160                 if (getstats(&total, &used))
   161                         return NULL;
   162 
   163                 if (total == 0)
   164                         return NULL;
   165 
   166                 return bprintf("%d", 100 * used / total);
   167         }
   168 
   169         const char *
   170         swap_total(const char *unused)
   171         {
   172                 int total, used;
   173 
   174                 if (getstats(&total, &used))
   175                         return NULL;
   176 
   177                 return fmt_human(total * 1024, 1024);
   178         }
   179 
   180         const char *
   181         swap_used(const char *unused)
   182         {
   183                 int total, used;
   184 
   185                 if (getstats(&total, &used))
   186                         return NULL;
   187 
   188                 return fmt_human(used * 1024, 1024);
   189         }
   190 #elif defined(__FreeBSD__)
   191         #include 
   192         #include 
   193         #include 
   194         #include 
   195         #include 
   196 
   197         static int getswapinfo(struct kvm_swap *swap_info, size_t size)
   198         {
   199                 kvm_t *kd;
   200 
   201                 kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, NULL);
   202                 if (kd == NULL) {
   203                         warn("kvm_openfiles '/dev/null':");
   204                         return 0;
   205                 }
   206 
   207                 if (kvm_getswapinfo(kd, swap_info, size, 0 /* Unused flags */) < 0) {
   208                         warn("kvm_getswapinfo:");
   209                         kvm_close(kd);
   210                         return 0;
   211                 }
   212 
   213                 kvm_close(kd);
   214                 return 1;
   215         }
   216 
   217         const char *
   218         swap_free(const char *unused)
   219         {
   220                 struct kvm_swap swap_info[1];
   221                 long used, total;
   222 
   223                 if (!getswapinfo(swap_info, 1))
   224                         return NULL;
   225 
   226                 total = swap_info[0].ksw_total;
   227                 used = swap_info[0].ksw_used;
   228 
   229                 return fmt_human((total - used) * getpagesize(), 1024);
   230         }
   231 
   232         const char *
   233         swap_perc(const char *unused)
   234         {
   235                 struct kvm_swap swap_info[1];
   236                 long used, total;
   237 
   238                 if (!getswapinfo(swap_info, 1))
   239                         return NULL;
   240 
   241                 total = swap_info[0].ksw_total;
   242                 used = swap_info[0].ksw_used;
   243 
   244                 return bprintf("%d", used * 100 / total);
   245         }
   246 
   247         const char *
   248         swap_total(const char *unused)
   249         {
   250                 struct kvm_swap swap_info[1];
   251                 long total;
   252 
   253                 if (!getswapinfo(swap_info, 1))
   254                         return NULL;
   255 
   256                 total = swap_info[0].ksw_total;
   257 
   258                 return fmt_human(total * getpagesize(), 1024);
   259         }
   260 
   261         const char *
   262         swap_used(const char *unused)
   263         {
   264                 struct kvm_swap swap_info[1];
   265                 long used;
   266 
   267                 if (!getswapinfo(swap_info, 1))
   268                         return NULL;
   269 
   270                 used = swap_info[0].ksw_used;
   271 
   272                 return fmt_human(used * getpagesize(), 1024);
   273         }
   274 #endif