#include <sys/types.h>
#include <sys/signal.h>
#include <sys/conf.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/swap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "systat.h"
static long blocksize;
static int hlen, nswap, rnswap;
static struct swapent *swap_devices;
void print_sw(void);
int read_sw(void);
int select_sw(void);
static void showswap(int i);
static void showtotal(void);
field_def fields_sw[] = {
{"DISK", 6, 16, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
{"BLOCKS", 5, 10, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
{"USED", 5, 10, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
{"", 40, 80, 1, FLD_ALIGN_BAR, -1, 0, 0, 100},
};
#define FLD_SW_NAME FIELD_ADDR(fields_sw,0)
#define FLD_SW_BLOCKS FIELD_ADDR(fields_sw,1)
#define FLD_SW_USED FIELD_ADDR(fields_sw,2)
#define FLD_SW_BAR FIELD_ADDR(fields_sw,3)
field_def *view_sw_0[] = {
FLD_SW_NAME, FLD_SW_BLOCKS, FLD_SW_USED, FLD_SW_BAR, NULL
};
struct view_manager swap_mgr = {
"Swap", select_sw, read_sw, NULL, print_header,
print_sw, keyboard_callback, NULL, NULL
};
field_view views_sw[] = {
{view_sw_0, "swap", '6', &swap_mgr},
{NULL, NULL, 0, NULL}
};
int
select_sw(void)
{
if (swap_devices == NULL || nswap == 0)
num_disp = 1;
else
num_disp = nswap;
if (nswap > 1)
num_disp++;
return (0);
}
int
read_sw(void)
{
num_disp = 1;
nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap < 0)
error("error: %s", strerror(errno));
if (nswap == 0)
return 0;
if (swap_devices)
(void)free(swap_devices);
swap_devices = calloc(nswap, sizeof(*swap_devices));
if (swap_devices == NULL)
return 0;
rnswap = swapctl(SWAP_STATS, (void *)swap_devices, nswap);
if (rnswap == -1 || nswap != rnswap)
return 0;
num_disp = nswap;
if (nswap > 1)
num_disp++;
return 0;
}
void
print_sw(void)
{
int n, count = 0;
if (swap_devices == NULL || nswap == 0) {
print_fld_str(FLD_SW_BAR, "No swap devices");
return;
}
for (n = dispstart; n < num_disp; n++) {
if (n >= nswap)
showtotal();
else
showswap(n);
count++;
if (maxprint > 0 && count >= maxprint)
break;
}
}
int
initswap(void)
{
field_view *v;
char *bs = getbsize(&hlen, &blocksize);
FLD_SW_BLOCKS->title = strdup(bs);
for (v = views_sw; v->name != NULL; v++)
add_view(v);
return(1);
}
static void
showswap(int i)
{
int d, used, xsize;
struct swapent *sep;
char *p;
d = blocksize / 512;
sep = &swap_devices[i];
p = strrchr(sep->se_path, '/');
p = p ? p+1 : sep->se_path;
print_fld_str(FLD_SW_NAME, p);
xsize = sep->se_nblks;
used = sep->se_inuse;
print_fld_uint(FLD_SW_BLOCKS, xsize / d);
print_fld_uint(FLD_SW_USED, used / d);
print_fld_bar(FLD_SW_BAR, 100 * used / xsize);
end_line();
}
static void
showtotal(void)
{
struct swapent *sep;
int d, i, avail, used, xsize, mfree;
d = blocksize / 512;
mfree = avail = 0;
for (sep = swap_devices, i = 0; i < nswap; i++, sep++) {
xsize = sep->se_nblks;
used = sep->se_inuse;
avail += xsize;
mfree += xsize - used;
}
used = avail - mfree;
print_fld_str(FLD_SW_NAME, "Total");
print_fld_uint(FLD_SW_BLOCKS, avail / d);
print_fld_uint(FLD_SW_USED, used / d);
print_fld_bar(FLD_SW_BAR, 100 * used / avail);
end_line();
}