1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-12-23 19:39:06 +00:00

* Applied 2 patches:

1) Add diskio for individual devices
        2) Improved output of units, added "short_units" option


git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@996 7f574dfc-610e-0410-a909-a81674777703
This commit is contained in:
Brenden Matthews 2008-02-09 02:21:06 +00:00
parent 8cb2b4079e
commit 433b564e14
13 changed files with 602 additions and 355 deletions

View File

@ -155,6 +155,8 @@ Kevin Lyles <kevinlyles at gmail dot com>
simplify round_to_int patch
goto width fix patch
offset width fix patch
individual diskio patch
short_units & human_readable patch
killfire
fs_used_perc and fs_bar_free patch

View File

@ -1,5 +1,10 @@
# $Id$
2008-02-08
* Applied 2 patches:
1) Add diskio for individual devices
2) Improved output of units, added "short_units" option
2008-01-05
* Applied some more submitted patches:
1) Add long forms of (most of) the command-line options.

73
README
View File

@ -370,12 +370,17 @@ CONFIGURATION SETTINGS
will be prompted to enter the password when Conky starts.
short_units
Shortens units to a single character (kiB->k, GiB->G, etc.). De-
fault is off.
stippled_borders
Border stippling (dashing) in pixels
total_run_times
Total number of times for Conky to update before quitting. Zero
Total number of times for Conky to update before quitting. Zero
makes Conky run forever
@ -388,9 +393,11 @@ CONFIGURATION SETTINGS
use_spacer
Adds spaces after certain objects to stop them from moving other
things around. Note that this only helps if you are using a mono
font, such as Bitstream Vera Sans Mono.
Adds spaces around certain objects to stop them from moving oth-
er things around. Arguments are left, right, and none (default).
The old true/false values are deprecated and default to
right/none respectively. Note that this only helps if you are
using a mono font, such as Bitstream Vera Sans Mono.
use_xft
@ -409,10 +416,10 @@ CONFIGURATION SETTINGS
VARIABLES
Colors are parsed using XParsecolor(), there might be a list of them:
/usr/X11R6/lib/X11/rgb.txt. Also, <http://sedition.com/perl/rgb.html>.
Color can be also in #rrggbb format (hex). Note that when displaying
bytes, power is 1024 and not 1000 so 1M really means 1024*1024 bytes
Colors are parsed using XParsecolor(), there might be a list of them:
/usr/X11R6/lib/X11/rgb.txt. Also, <http://sedition.com/perl/rgb.html>.
Color can be also in #rrggbb format (hex). Note that when displaying
bytes, power is 1024 and not 1000 so 1M really means 1024*1024 bytes
and not 1000*1000.
addr interface
@ -460,7 +467,7 @@ VARIABLES
apm_battery_time
Display remaining APM battery life in hh:mm:ss or "unknown" if
Display remaining APM battery life in hh:mm:ss or "unknown" if
AC adapterstatus is on-line or charging (FreeBSD only)
@ -517,8 +524,8 @@ VARIABLES
battery (num)
Battery status and remaining percentage capacity of ACPI or APM
battery. ACPI battery number can be given as argument (default
Battery status and remaining percentage capacity of ACPI or APM
battery. ACPI battery number can be given as argument (default
is BAT0).
@ -533,7 +540,7 @@ VARIABLES
battery_time (num)
Battery charge/discharge time remaining of ACPI battery. ACPI
Battery charge/discharge time remaining of ACPI battery. ACPI
battery number can be given as argument (default is BAT0).
@ -603,49 +610,53 @@ VARIABLES
cpu (cpuN)
CPU usage in percents. For SMP machines, the CPU number can be
provided as an argument. ${cpu cpu0} is the total usage, and
CPU usage in percents. For SMP machines, the CPU number can be
provided as an argument. ${cpu cpu0} is the total usage, and
${cpu cpuX} (X >= 1) are individual CPUs.
cpubar (cpu number) (height),(width)
Bar that shows CPU usage, height is bar's height in pixels. See
Bar that shows CPU usage, height is bar's height in pixels. See
$cpu for more info on SMP.
cpugraph (cpu number) (height),(width) (gradient colour 1) (gradient
cpugraph (cpu number) (height),(width) (gradient colour 1) (gradient
colour 2)
CPU usage graph, with optional colours in hex, minus the #. See
CPU usage graph, with optional colours in hex, minus the #. See
$cpu for more info on SMP.
diskio Displays current disk IO.
diskio (device)
Displays current disk IO. Device is optional, and takes the form
of sda for /dev/sda. Individual partitions are allowed.
diskiograph (height),(width) (gradient colour 1) (gradient colour 2)
(scale)
diskiograph (device) (height),(width) (gradient colour 1) (gradient
colour 2) (scale)
Disk IO graph, colours defined in hex, minus the #. If scale is
non-zero, it becomes the scale for the graph.
diskio_read
Displays current disk IO for reads.
diskio_read (device)
Displays current disk IO for reads. Device as in diskio.
diskiograph_read (height),(width) (gradient colour 1) (gradient colour
2) (scale)
diskiograph_read (device) (height),(width) (gradient colour 1) (gradi-
ent colour 2) (scale)
Disk IO graph for reads, colours defined in hex, minus the #. If
scale is non-zero, it becomes the scale for the graph.
scale is non-zero, it becomes the scale for the graph. Device as
in diskio.
diskio_write
Displays current disk IO for writes.
diskio_write (device)
Displays current disk IO for writes. Device as in diskio.
diskiograph_write (height),(width) (gradient colour 1) (gradient colour
2) (scale)
Disk IO graph for writes, colours defined in hex, minus the #.
If scale is non-zero, it becomes the scale for the graph.
diskiograph_write (device) (height),(width) (gradient colour 1) (gradi-
ent colour 2) (scale)
Disk IO graph for writes, colours defined in hex, minus the #.
If scale is non-zero, it becomes the scale for the graph. Device
as in diskio.
downspeed net

View File

@ -385,6 +385,13 @@
<para></para></listitem>
</varlistentry>
<varlistentry>
<term><command><option>short_units</option></command></term>
<listitem>
Shortens units to a single character (kiB->k, GiB->G, etc.). Default is off.
<para></para></listitem>
</varlistentry>
<varlistentry>
<term><command><option>stippled_borders</option></command></term>
<listitem>
@ -416,7 +423,7 @@
<varlistentry>
<term><command><option>use_spacer</option></command></term>
<listitem>
Adds spaces after certain objects to stop them from moving other things around. Note that this only helps if you are using a mono font, such as Bitstream Vera Sans Mono.
Adds spaces around certain objects to stop them from moving other things around. Arguments are left, right, and none (default). The old true/false values are deprecated and default to right/none respectively. Note that this only helps if you are using a mono font, such as Bitstream Vera Sans Mono.
<para></para></listitem>
</varlistentry>

View File

@ -352,6 +352,10 @@ Pad percentages to this many decimals (0 = no padding)
\fB\*(T<\fBpop3\fR\*(T>\fR
Default global POP3 server. Arguments are: "host user pass [-i interval] [-p port] [-e command]". Default port is 110, default interval is 5 minutes. If the password is supplied as '*', you will be prompted to enter the password when Conky starts.
.TP
\fB\*(T<\fBshort_units\fR\*(T>\fR
Shortens units to a single character (kiB->k, GiB->G, etc.). Default is off.
.TP
\fB\*(T<\fBstippled_borders\fR\*(T>\fR
Border stippling (dashing) in pixels
@ -370,7 +374,7 @@ Boolean value, if true, text is rendered in upper case
.TP
\fB\*(T<\fBuse_spacer\fR\*(T>\fR
Adds spaces after certain objects to stop them from moving other things around. Note that this only helps if you are using a mono font, such as Bitstream Vera Sans Mono.
Adds spaces around certain objects to stop them from moving other things around. Arguments are left, right, and none (default). The old true/false values are deprecated and default to right/none respectively. Note that this only helps if you are using a mono font, such as Bitstream Vera Sans Mono.
.TP
\fB\*(T<\fBuse_xft\fR\*(T>\fR
@ -600,28 +604,28 @@ Bar that shows CPU usage, height is bar's height in pixels. See $cpu for more in
CPU usage graph, with optional colours in hex, minus the #. See $cpu for more info on SMP.
.TP
\fB\*(T<\fBdiskio\fR\*(T>\fR
Displays current disk IO.
\fB\*(T<\fBdiskio\fR\*(T>\fR \*(T<\fB(device)\fR\*(T>
Displays current disk IO. Device is optional, and takes the form of sda for /dev/sda. Individual partitions are allowed.
.TP
\fB\*(T<\fBdiskiograph\fR\*(T>\fR \*(T<\fB(height),(width) (gradient colour 1) (gradient colour 2) (scale)\fR\*(T>
\fB\*(T<\fBdiskiograph\fR\*(T>\fR \*(T<\fB(device) (height),(width) (gradient colour 1) (gradient colour 2) (scale)\fR\*(T>
Disk IO graph, colours defined in hex, minus the #. If scale is non-zero, it becomes the scale for the graph.
.TP
\fB\*(T<\fBdiskio_read\fR\*(T>\fR
Displays current disk IO for reads.
\fB\*(T<\fBdiskio_read\fR\*(T>\fR \*(T<\fB(device)\fR\*(T>
Displays current disk IO for reads. Device as in diskio.
.TP
\fB\*(T<\fBdiskiograph_read\fR\*(T>\fR \*(T<\fB(height),(width) (gradient colour 1) (gradient colour 2) (scale)\fR\*(T>
Disk IO graph for reads, colours defined in hex, minus the #. If scale is non-zero, it becomes the scale for the graph.
\fB\*(T<\fBdiskiograph_read\fR\*(T>\fR \*(T<\fB(device) (height),(width) (gradient colour 1) (gradient colour 2) (scale)\fR\*(T>
Disk IO graph for reads, colours defined in hex, minus the #. If scale is non-zero, it becomes the scale for the graph. Device as in diskio.
.TP
\fB\*(T<\fBdiskio_write\fR\*(T>\fR
Displays current disk IO for writes.
\fB\*(T<\fBdiskio_write\fR\*(T>\fR \*(T<\fB(device)\fR\*(T>
Displays current disk IO for writes. Device as in diskio.
.TP
\fB\*(T<\fBdiskiograph_write\fR\*(T>\fR \*(T<\fB(height),(width) (gradient colour 1) (gradient colour 2) (scale)\fR\*(T>
Disk IO graph for writes, colours defined in hex, minus the #. If scale is non-zero, it becomes the scale for the graph.
\fB\*(T<\fBdiskiograph_write\fR\*(T>\fR \*(T<\fB(device) (height),(width) (gradient colour 1) (gradient colour 2) (scale)\fR\*(T>
Disk IO graph for writes, colours defined in hex, minus the #. If scale is non-zero, it becomes the scale for the graph. Device as in diskio.
.TP
\fB\*(T<\fBdownspeed\fR\*(T>\fR \*(T<\fBnet\fR\*(T>

View File

@ -475,16 +475,17 @@
<varlistentry>
<term>
<command><option>diskio</option></command>
<option>(device)</option>
</term>
<listitem>
Displays current disk IO.
Displays current disk IO. Device is optional, and takes the form of sda for /dev/sda. Individual partitions are allowed.
<para></para></listitem>
</varlistentry>
<varlistentry>
<term>
<command><option>diskiograph</option></command>
<option>(height),(width) (gradient colour 1) (gradient colour 2) (scale)</option>
<option>(device) (height),(width) (gradient colour 1) (gradient colour 2) (scale)</option>
</term>
<listitem>
Disk IO graph, colours defined in hex, minus the #. If scale is non-zero, it becomes the scale for the graph.
@ -494,38 +495,40 @@
<varlistentry>
<term>
<command><option>diskio_read</option></command>
<option>(device)</option>
</term>
<listitem>
Displays current disk IO for reads.
Displays current disk IO for reads. Device as in diskio.
<para></para></listitem>
</varlistentry>
<varlistentry>
<term>
<command><option>diskiograph_read</option></command>
<option>(height),(width) (gradient colour 1) (gradient colour 2) (scale)</option>
<option>(device) (height),(width) (gradient colour 1) (gradient colour 2) (scale)</option>
</term>
<listitem>
Disk IO graph for reads, colours defined in hex, minus the #. If scale is non-zero, it becomes the scale for the graph.
Disk IO graph for reads, colours defined in hex, minus the #. If scale is non-zero, it becomes the scale for the graph. Device as in diskio.
<para></para></listitem>
</varlistentry>
<varlistentry>
<term>
<command><option>diskio_write</option></command>
<option>(device)</option>
</term>
<listitem>
Displays current disk IO for writes.
Displays current disk IO for writes. Device as in diskio.
<para></para></listitem>
</varlistentry>
<varlistentry>
<term>
<command><option>diskiograph_write</option></command>
<option>(height),(width) (gradient colour 1) (gradient colour 2) (scale)</option>
<option>(device) (height),(width) (gradient colour 1) (gradient colour 2) (scale)</option>
</term>
<listitem>
Disk IO graph for writes, colours defined in hex, minus the #. If scale is non-zero, it becomes the scale for the graph.
Disk IO graph for writes, colours defined in hex, minus the #. If scale is non-zero, it becomes the scale for the graph. Device as in diskio.
<para></para></listitem>
</varlistentry>

View File

@ -46,7 +46,7 @@ xmms2 = xmms2.c
endif
if BUILD_LINUX
linux = linux.c top.c
linux = linux.c top.c diskio.c
PTHREAD_LIBS = -lpthread
endif
@ -127,6 +127,7 @@ EXTRA_DIST = \
openbsd.c \
solaris.c \
top.h \
diskio.h \
x11.c \
xmms2.c

View File

@ -164,6 +164,8 @@ static int selected_font = 0;
static int font_count = -1;
struct font_list *fonts = NULL;
static char *suffixes[] = { "B", "kiB", "MiB", "GiB", "TiB", "PiB", "" };
#ifdef XFT
#define font_height() (use_xft ? (fonts[selected_font].xftfont->ascent + fonts[selected_font].xftfont->descent) : \
@ -741,46 +743,73 @@ static void new_graph(char *buf, int w, int h, unsigned int first_colour, unsign
}
}
static const char *scan_graph(const char *args, int *w, int *h, unsigned int *first_colour, unsigned int *last_colour, unsigned int *scale)
static char *scan_graph(const char *args, int *w, int *h,
unsigned int *first_colour, unsigned int *last_colour,
unsigned int *scale)
{
*w = 0; /* zero width means all space that is available */
*h = 25;
*first_colour = 0;
*last_colour = 0;
char buf[64];
/* graph's argument is either height or height,width */
if (args) {
if (sscanf(args, "%*s %d,%d %x %x %i", h, w, first_colour, last_colour, scale) < 5) {
if (sscanf(args, "%*s %d,%d %x %x", h, w, first_colour, last_colour) < 4) {
*scale = 0;
if (sscanf(args, "%d,%d %x %x %i", h, w, first_colour, last_colour, scale) < 5) {
*scale = 0;
if (sscanf(args, "%d,%d %x %x", h, w, first_colour, last_colour) < 4) {
*w = 0;
*h = 25;
if (sscanf(args, "%*s %x %x %i", first_colour, last_colour, scale) < 3) {
*w = 0;
*h = 25;
*scale = 0;
if (sscanf(args, "%*s %x %x", first_colour, last_colour) < 2) {
*w = 0;
*h = 25;
if (sscanf(args, "%x %x %i", first_colour, last_colour, scale) < 3) {
*first_colour = 0;
*last_colour = 0;
*scale = 0;
if (sscanf(args, "%x %x", first_colour, last_colour) < 2) {
*first_colour = 0;
*last_colour = 0;
if (sscanf(args, "%d,%d %i", h, w, scale) < 3) {
*first_colour = 0;
*last_colour = 0;
*scale = 0;
if (sscanf(args, "%d,%d", h, w) < 2) {
*first_colour = 0;
*last_colour = 0;
sscanf(args, "%*s %d,%d", h, w);
}}}}}}}}}}} // haha
return args;
if (sscanf(args, "%d,%d %x %x %i", h, w, first_colour, last_colour,
scale) == 5) {
return NULL;
}
*scale = 0;
if (sscanf(args, "%d,%d %x %x", h, w, first_colour, last_colour) == 4) {
return NULL;
}
if (sscanf(args, "%63s %d,%d %x %x %i", buf, h, w, first_colour,
last_colour, scale) == 6) {
return strdup(buf);
}
*scale = 0;
if (sscanf(args, "%63s %d,%d %x %x", buf, h, w, first_colour,
last_colour) == 5) {
return strdup(buf);
}
buf[0] = '\0';
*h = 25;
*w = 0;
if (sscanf(args, "%x %x %i", first_colour, last_colour, scale) == 3) {
return NULL;
}
*scale = 0;
if (sscanf(args, "%x %x", first_colour, last_colour) == 2) {
return NULL;
}
if (sscanf(args, "%63s %x %x %i", buf, first_colour, last_colour,
scale) == 4) {
return strdup(buf);
}
*scale = 0;
if (sscanf(args, "%63s %x %x", buf, first_colour, last_colour) == 3) {
return strdup(buf);
}
buf[0] = '\0';
*first_colour = 0;
*last_colour = 0;
if (sscanf(args, "%d,%d %i", h, w, scale) == 3) {
return NULL;
}
*scale = 0;
if (sscanf(args, "%d,%d", h, w) == 2) {
return NULL;
}
if (sscanf(args, "%63s %d,%d %i", buf, h, w, scale) < 4) {
*scale = 0;
//TODO: check the return value and throw an error?
sscanf(args, "%63s %d,%d", buf, h, w);
}
return strdup(buf);
}
if (buf[0] == '\0') {
return NULL;
} else {
return strdup(buf);
}
}
@ -879,26 +908,80 @@ static void convert_escapes(char *buf)
*p = '\0';
}
/* Prints anything normally printed with snprintf according to the current value
* of use_spacer. Actually slightly more flexible than snprintf, as you can
* safely specify the destination buffer as one of your inputs. */
static int spaced_print(char *buf, int size, char *format, int width,
char *func_name, ...) {
int len;
va_list argp;
char *tempbuf = malloc(size * sizeof(char));
// Passes the varargs along to vsnprintf
va_start(argp, func_name);
vsnprintf(tempbuf, size, format, argp);
va_end(argp);
switch (use_spacer) {
case NO_SPACER:
len = snprintf(buf, size, "%s", tempbuf);
break;
case LEFT_SPACER:
len = snprintf(buf, width, "%*s", width - 1, tempbuf);
break;
case RIGHT_SPACER:
len = snprintf(buf, width, "%-*s", width - 1, tempbuf);
break;
default:
CRIT_ERR("%s encountered invalid use_spacer value (%d)", func_name,
use_spacer);
}
free(tempbuf);
return len;
}
/* converts from bytes to human readable format (k, M, G, T) */
static void human_readable(long long a, char *buf, int size)
static void human_readable(long long num, char *buf, int size, char *func_name)
{
// Strange conditional due to possible overflows
if(a / 1024 / 1024 / 1024.0 > 1024.0){
snprintf(buf, size, "%.2fTiB", (a / 1024 / 1024 / 1024) / 1024.0);
char ** suffix = suffixes;
float fnum;
int precision, len;
static const int WIDTH = 10, SHORT_WIDTH = 8;
if (num < 1024LL) {
if (short_units) {
spaced_print(buf, size, "%lld%c", SHORT_WIDTH, func_name, num,
**suffix);
} else {
spaced_print(buf, size, "%lld%s", WIDTH, func_name, num, *suffix);
}
return;
}
else if (a >= 1024 * 1024 * 1024) {
snprintf(buf, size, "%.2fGiB", (a / 1024 / 1024) / 1024.0);
while (num / 1024 >= 1000LL && **(suffix + 2)) {
num /= 1024;
suffix++;
}
else if (a >= 1024 * 1024) {
double m = (a / 1024) / 1024.0;
if (m >= 100.0)
snprintf(buf, size, "%.0fMiB", m);
else
snprintf(buf, size, "%.1fMiB", m);
} else if (a >= 1024)
snprintf(buf, size, "%LdKiB", a / (long long) 1024);
else
snprintf(buf, size, "%LdB", a);
suffix++;
fnum = num / 1024.0;
precision = 3;
do {
precision--;
if (precision < 0) {
break;
}
if (short_units) {
len = spaced_print(buf, size, "%.*f%c", SHORT_WIDTH, func_name,
precision, fnum, **suffix);
} else {
len = spaced_print(buf, size, "%.*f%s", WIDTH, func_name, precision,
fnum, *suffix);
}
} while (len >= (short_units ? SHORT_WIDTH : WIDTH) || len >= size);
}
/* text handling */
@ -1161,8 +1244,9 @@ struct text_object {
int i; /* some integer */
long l; /* some other integer */
unsigned int sensor;
struct net_stat *net;
struct net_stat *net;
struct fs_stat *fs;
struct diskio_stat *diskio;
unsigned char loadavg[3];
unsigned int cpu_index;
struct mail_s *mail;
@ -2340,22 +2424,65 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
obj->data.cpu_index = 0;
}
END OBJ(cpugraph, INFO_CPU)
if (arg) {
if (strncmp(arg, "cpu", 3) == 0 && isdigit(arg[3])) {
obj->data.cpu_index = atoi(&arg[3]);
arg += 4;
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
&obj->e);
if (buf) {
if (strncmp(buf, "cpu", 3) == 0 && isdigit(buf[3])) {
obj->data.cpu_index = atoi(&buf[3]);
} else {
obj->data.cpu_index = 0;
}
(void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
} else {
(void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
obj->data.cpu_index = 0;
free(buf);
}
END OBJ(diskio, INFO_DISKIO)
if (arg) {
obj->data.diskio = prepare_diskio_stat(arg);
} else {
obj->data.diskio = NULL;
}
END OBJ(diskio_read, INFO_DISKIO)
if (arg) {
obj->data.diskio = prepare_diskio_stat(arg);
} else {
obj->data.diskio = NULL;
}
END OBJ(diskio_write, INFO_DISKIO)
END OBJ(diskiograph, INFO_DISKIO) (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
END OBJ(diskiograph_read, INFO_DISKIO) (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
END OBJ(diskiograph_write, INFO_DISKIO) (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
if (arg) {
obj->data.diskio = prepare_diskio_stat(arg);
} else {
obj->data.diskio = NULL;
}
END OBJ(diskiograph, INFO_DISKIO)
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
&obj->e);
if (buf) {
obj->data.diskio = prepare_diskio_stat(buf);
free(buf);
} else {
obj->data.diskio = NULL;
}
END OBJ(diskiograph_read, INFO_DISKIO)
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
&obj->e);
if (buf) {
obj->data.diskio = prepare_diskio_stat(buf);
free(buf);
} else {
obj->data.diskio = NULL;
}
END OBJ(diskiograph_write, INFO_DISKIO)
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
&obj->e);
if (buf) {
obj->data.diskio = prepare_diskio_stat(buf);
free(buf);
} else {
obj->data.diskio = NULL;
}
END OBJ(color, 0)
#ifdef X11
obj->data.l = arg ? get_x11_color(arg) : default_fg_color;
@ -2397,16 +2524,13 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
CRIT_ERR("downspeedf needs argument");
}
END OBJ(downspeedgraph, INFO_NET)
(void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
char buf[64];
sscanf(arg, "%63s %*i,%*i %*i", buf);
obj->data.net = get_net_stat(buf);
if (sscanf(arg, "%*s %d,%d %*d", &obj->b, &obj->a) <= 1) {
if (sscanf(arg, "%*s %d,%d", &obj->b, &obj->a) <= 1) {
obj->a = 0;
obj->b = 25;
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
&obj->e);
if (buf) {
obj->data.net = get_net_stat(buf);
free(buf);
}
}
END OBJ(else, 0)
if (blockdepth) {
(text_objects[blockstart[blockdepth - 1]]).data.ifblock.pos = object_count;
@ -2963,7 +3087,12 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
END OBJ(membar, INFO_MEM)
(void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
END OBJ(memgraph, INFO_MEM)
(void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
&obj->e);
if (buf) {
free(buf);
}
END OBJ(mixer, INFO_MIXER) obj->data.l = mixer_init(arg);
END OBJ(mixerl, INFO_MIXER) obj->data.l = mixer_init(arg);
END OBJ(mixerr, INFO_MIXER) obj->data.l = mixer_init(arg);
@ -3113,16 +3242,13 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
}
END OBJ(upspeedgraph, INFO_NET)
(void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
char buf[64];
sscanf(arg, "%63s %*i,%*i %*i", buf);
obj->data.net = get_net_stat(buf);
if (sscanf(arg, "%*s %d,%d %*d", &obj->b, &obj->a) <= 1) {
if (sscanf(arg, "%*s %d,%d", &obj->a, &obj->a) <= 1) {
obj->a = 0;
obj->b = 25;
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
&obj->e);
if (buf) {
obj->data.net = get_net_stat(buf);
free(buf);
}
}
END OBJ(uptime_short, INFO_UPTIME) END OBJ(uptime, INFO_UPTIME) END
#ifndef __OpenBSD__
OBJ(adt746xcpu, 0) END OBJ(adt746xfan, 0) END
@ -3688,29 +3814,14 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
#ifndef __OpenBSD__
OBJ(acpitemp) {
/* does anyone have decimals in acpi temperature? */
if (!use_spacer)
snprintf(p, p_max_size, "%d", (int)
get_acpi_temperature(obj->
data.
i));
else
snprintf(p, 5, "%d ", (int)
get_acpi_temperature(obj->
data.
i));
spaced_print(p, p_max_size, "%d", 5, "acpitemp",
round_to_int(get_acpi_temperature(obj->data.i)));
}
OBJ(acpitempf) {
/* does anyone have decimals in acpi temperature? */
if (!use_spacer)
snprintf(p, p_max_size, "%d", (int)
((get_acpi_temperature(obj->
data.
i)+ 40) * 9.0 / 5 - 40));
else
snprintf(p, 5, "%d ", (int)
((get_acpi_temperature(obj->
data.
i)+ 40) * 9.0 / 5 - 40));
spaced_print(p, p_max_size, "%d", 5, "acpitemp",
round_to_int((get_acpi_temperature(obj->data.i) + 40) *
9.0 / 5 - 40));
}
#endif /* !__OpenBSD__ */
OBJ(freq) {
@ -3754,24 +3865,23 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
snprintf(p, p_max_size, "%s", obj->data.net->ap);
}
OBJ(wireless_link_qual) {
if (!use_spacer)
snprintf(p, p_max_size, "%d", obj->data.net->link_qual);
else
snprintf(p, 4, "%d ", obj->data.net->link_qual);
spaced_print(p, p_max_size, "%d", 4, "wireless_link_qual",
obj->data.net->link_qual);
}
OBJ(wireless_link_qual_max) {
if (!use_spacer)
snprintf(p, p_max_size, "%d", obj->data.net->link_qual_max);
else
snprintf(p, 4, "%d ", obj->data.net->link_qual_max);
spaced_print(p, p_max_size, "%d", 4,
"wireless_link_qual_max", obj->data.net->link_qual_max);
}
OBJ(wireless_link_qual_perc) {
if(obj->data.net->link_qual_max > 0) {
if (!use_spacer)
snprintf(p, p_max_size, "%.0f%%", (double)obj->data.net->link_qual / obj->data.net->link_qual_max * 100);
else
snprintf(p, 5, "%.0f%% ", (double)obj->data.net->link_qual / obj->data.net->link_qual_max * 100);
} else snprintf(p, p_max_size, "unk");
spaced_print(p, p_max_size, "%.0f%%", 5,
"wireless_link_qual_perc",
(double) obj->data.net->link_qual /
obj->data.net->link_qual_max * 100);
} else {
spaced_print(p, p_max_size, "unk", 5,
"wireless_link_qual_perc");
}
}
OBJ(wireless_link_bar) {
new_bar(p, obj->a, obj->b, ((double)obj->data.net->link_qual/obj->data.net->link_qual_max)*255.0);
@ -3781,26 +3891,16 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
#endif /* __linux__ */
OBJ(freq_dyn) {
if (use_spacer) {
get_freq_dynamic(p, 6, "%.0f ", 1 );
} else {
get_freq_dynamic(p, p_max_size, "%.0f", 1 );
}
get_freq_dynamic(p, p_max_size, "%.0f", 1);
spaced_print(p, p_max_size, "%s", 6, "freq_dyn", p);
}
OBJ(freq_dyn_g) {
if (use_spacer) {
#ifndef __OpenBSD__
get_freq_dynamic(p, 6, "%'.2f ", 1000);
get_freq_dynamic(p, p_max_size, "%'.2f", 1000);
#else
get_freq_dynamic(p, 6, "%.2f ", 1000);
get_freq_dynamic(p, p_max_size, "%.2f", 1000);
#endif
} else {
#ifndef __OpenBSD__
get_freq_dynamic(p, p_max_size, "%'.2f", 1000);
#else
get_freq_dynamic(p, p_max_size, "%.2f", 1000);
#endif
}
spaced_print(p, p_max_size, "%s", 6, "freq_dyn", p);
}
#ifndef __OpenBSD__
OBJ(adt746xcpu) {
@ -3830,25 +3930,20 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
}
#endif /* __OpenBSD__ */
OBJ(buffers) {
human_readable(cur->buffers * 1024, p, 255);
human_readable(cur->buffers * 1024, p, 255, "buffers");
}
OBJ(cached) {
human_readable(cur->cached * 1024, p, 255);
human_readable(cur->cached * 1024, p, 255, "buffers");
}
OBJ(cpu) {
if (obj->data.cpu_index > info.cpu_count) {
printf("obj->data.cpu_index %i info.cpu_count %i", obj->data.cpu_index, info.cpu_count);
printf("obj->data.cpu_index %i info.cpu_count %i",
obj->data.cpu_index, info.cpu_count);
CRIT_ERR("attempting to use more CPUs then you have!");
}
if (!use_spacer)
snprintf(p, p_max_size, "%*d", pad_percents,
round_to_int(cur->cpu_usage[obj->data.cpu_index] *
100.0));
else
snprintf(p, 4, "%*d ",
pad_percents,
round_to_int(cur->cpu_usage[obj->data.cpu_index] *
100.0));
spaced_print(p, p_max_size, "%*d", 4, "cpu", pad_percents,
round_to_int(cur->cpu_usage[obj->data.cpu_index] *
100.0));
}
OBJ(cpubar) {
new_bar(p, obj->a,
@ -4011,88 +4106,71 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
new_font(p, obj->data.s);
}
#endif
void format_diskio(unsigned int diskio_value)
{
if (!use_spacer) {
if (diskio_value > 1024*1024) {
snprintf(p, p_max_size, "%.1fGiB",
(double)diskio_value/1024/1024);
} else if (diskio_value > 1024) {
snprintf(p, p_max_size, "%.1fMiB",
(double)diskio_value/1024);
} else if (diskio_value > 0) {
snprintf(p, p_max_size, "%dKiB", diskio_value);
} else {
snprintf(p, p_max_size, "%dB", diskio_value);
}
/* TODO: move this correction from kB to kB/s elsewhere
* (or get rid of it??) */
OBJ(diskio) {
if (obj->data.diskio) {
human_readable((obj->data.diskio->current / update_interval) * 1024LL, p, p_max_size, "diskio");
} else {
if (diskio_value > 1024*1024) {
snprintf(p, 12, "%.1fGiB ",
(double)diskio_value/1024/1024);
} else if (diskio_value > 1024) {
snprintf(p, 12, "%.1fMiB ",
(double)diskio_value/1024);
} else if (diskio_value > 0) {
snprintf(p, 12, "%dKiB ", diskio_value);
} else {
snprintf(p, 12, "%dB ", diskio_value);
}
human_readable(diskio_value * 1024LL, p, p_max_size, "diskio");
}
}
OBJ(diskio) {
format_diskio(diskio_value);
}
OBJ(diskio_write) {
format_diskio(diskio_write_value);
if (obj->data.diskio) {
human_readable((obj->data.diskio->current_write / update_interval) * 1024LL, p, p_max_size,
"diskio_write");
} else {
human_readable(diskio_write_value * 1024LL, p, p_max_size,
"diskio_write");
}
}
OBJ(diskio_read) {
if (obj->data.diskio) {
human_readable((obj->data.diskio->current_read / update_interval) * 1024LL, p, p_max_size,
"diskio_read");
} else {
human_readable(diskio_read_value * 1024LL, p, p_max_size,
"diskio_read");
}
}
OBJ(diskiograph) {
if (obj->data.diskio) {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
obj->data.diskio->current, obj->e, 1);
} else {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
diskio_value, obj->e, 1);
}
}
OBJ(diskiograph_read) {
if (obj->data.diskio) {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
obj->data.diskio->current_read, obj->e, 1);
} else {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
diskio_read_value, obj->e, 1);
}
}
OBJ(diskiograph_write) {
if (obj->data.diskio) {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
obj->data.diskio->current_write, obj->e, 1);
} else {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
diskio_write_value, obj->e, 1);
}
}
OBJ(diskio_read) {
format_diskio(diskio_read_value);
}
OBJ(diskiograph) {
new_graph(p, obj->a,
obj->b, obj->c, obj->d,
diskio_value, obj->e, 1);
}
OBJ(diskiograph_read) {
new_graph(p, obj->a,
obj->b, obj->c, obj->d,
diskio_read_value, obj->e, 1);
}
OBJ(diskiograph_write) {
new_graph(p, obj->a,
obj->b, obj->c, obj->d,
diskio_write_value, obj->e, 1);
}
OBJ(downspeed) {
if (!use_spacer) {
snprintf(p, p_max_size, "%d",
(int) (obj->data.net->
recv_speed /
1024));
} else
snprintf(p, 6, "%d ",
(int) (obj->data.net->
recv_speed /
1024));
spaced_print(p, p_max_size, "%d", 6, "downspeed",
round_to_int(obj->data.net->recv_speed / 1024));
}
OBJ(downspeedf) {
if (!use_spacer)
snprintf(p, p_max_size, "%.1f",
obj->data.net->
recv_speed / 1024.0);
else
snprintf(p, 8, "%.1f ",
obj->data.net->
recv_speed / 1024.0);
spaced_print(p, p_max_size, "%.1f", 8, "downspeedf",
obj->data.net->recv_speed / 1024.0);
}
OBJ(downspeedgraph) {
/*
if (obj->data.net->recv_speed == 0)
obj->data.net->recv_speed = 0.01;
*/
new_graph(p, obj->a, obj->b, obj->c, obj->d,
(obj->data.net->recv_speed /
1024.0), obj->e, 1);
(obj->data.net->recv_speed / 1024.0), obj->e, 1);
}
OBJ(else) {
if (!if_jumped) {
@ -4472,9 +4550,9 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
}
}
OBJ(fs_free) {
if (obj->data.fs != NULL)
human_readable(obj->data.fs->avail,
p, 255);
if (obj->data.fs != NULL) {
human_readable(obj->data.fs->avail, p, 255, "fs_free");
}
}
OBJ(fs_free_perc) {
if (obj->data.fs != NULL) {
@ -4492,15 +4570,16 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
}
}
OBJ(fs_size) {
if (obj->data.fs != NULL)
human_readable(obj->data.fs->size,
p, 255);
if (obj->data.fs != NULL) {
human_readable(obj->data.fs->size, p, 255, "fs_size");
}
}
OBJ(fs_used) {
if (obj->data.fs != NULL)
if (obj->data.fs != NULL) {
human_readable(obj->data.fs->size -
(obj->data.fs->free ? obj->data.fs->free :obj->data.fs->avail),
p, 255);
(obj->data.fs->free ? obj->data.fs->free :
obj->data.fs->avail), p, 255, "fs_used");
}
}
OBJ(fs_bar_free) {
if (obj->data.fs != NULL) {
@ -4747,23 +4826,15 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
/* memory stuff */
OBJ(mem) {
human_readable(cur->mem * 1024, p, 255);
human_readable(cur->mem * 1024, p, 255, "mem");
}
OBJ(memmax) {
human_readable(cur->memmax * 1024, p, 255);
human_readable(cur->memmax * 1024, p, 255, "memmax");
}
OBJ(memperc) {
if (cur->memmax) {
if (!use_spacer)
snprintf(p, p_max_size, "%*Lu",
pad_percents,
(cur->mem * 100) /
(cur->memmax));
else
snprintf(p, 4, "%*Lu ",
pad_percents,
(cur->mem * 100) /
(cur->memmax));
spaced_print(p, p_max_size, "%*Lu", 4, "memperc",
pad_percents, cur->mem * 100 / cur->memmax);
}
}
OBJ(membar) {
@ -4833,19 +4904,11 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
new_outline(p, obj->data.l);
}
OBJ(processes) {
if (!use_spacer)
snprintf(p, p_max_size, "%hu", cur->procs);
else
snprintf(p, 5, "%hu ",
cur->procs);
spaced_print(p, p_max_size, "%hu", 5, "processes", cur->procs);
}
OBJ(running_processes) {
if (!use_spacer)
snprintf(p, p_max_size, "%hu",
cur->run_procs);
else
snprintf(p, 3, "%hu ",
cur->run_procs);
spaced_print(p, p_max_size, "%hu", 3, "running_processes",
cur->run_procs);
}
OBJ(text) {
snprintf(p, p_max_size, "%s", obj->data.s);
@ -4858,28 +4921,17 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
obj->data.pair.b);
}
OBJ(swap) {
human_readable(cur->swap * 1024, p, 255);
human_readable(cur->swap * 1024, p, 255, "swap");
}
OBJ(swapmax) {
human_readable(cur->swapmax * 1024, p,
255);
human_readable(cur->swapmax * 1024, p, 255, "swapmax");
}
OBJ(swapperc) {
if (cur->swapmax == 0) {
strncpy(p, "No swap", 255);
strncpy(p, "No swap", p_max_size);
} else {
if (!use_spacer)
snprintf(p, 255, "%*Lu",
pad_percents,
(cur->swap *
100) /
cur->swapmax);
else
snprintf(p, 4, "%*Lu ",
pad_percents,
(cur->swap *
100) /
cur->swapmax);
spaced_print(p, p_max_size, "%*Lu", 4, "swapperc",
pad_percents, cur->swap * 100 / cur->swapmax);
}
}
OBJ(swapbar) {
@ -4922,46 +4974,25 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
// Needless to free oldTZ since getenv gives ptr to static data
}
OBJ(totaldown) {
human_readable(obj->data.net->recv, p,
255);
human_readable(obj->data.net->recv, p, 255, "totaldown");
}
OBJ(totalup) {
human_readable(obj->data.net->trans, p,
255);
human_readable(obj->data.net->trans, p, 255, "totalup");
}
OBJ(updates) {
snprintf(p, p_max_size, "%d", total_updates);
}
OBJ(upspeed) {
if (!use_spacer)
snprintf(p, p_max_size, "%d",
(int) (obj->data.net->
trans_speed /
1024));
else
snprintf(p, 6, "%d ",
(int) (obj->data.net->
trans_speed /
1024));
spaced_print(p, p_max_size, "%d", 6, "upspeed",
round_to_int(obj->data.net->trans_speed / 1024));
}
OBJ(upspeedf) {
if (!use_spacer)
snprintf(p, p_max_size, "%.1f",
obj->data.net->
trans_speed / 1024.0);
else
snprintf(p, 8, "%.1f ",
obj->data.net->
trans_speed / 1024.0);
spaced_print(p, p_max_size, "%.1f", 8, "upspeedf",
obj->data.net->trans_speed / 1024.0);
}
OBJ(upspeedgraph) {
/*
if (obj->data.net->trans_speed == 0)
obj->data.net->trans_speed = 0.01;
*/
new_graph(p, obj->a, obj->b, obj->c, obj->d,
(obj->data.net->trans_speed /
1024.0), obj->e, 1);
(obj->data.net->trans_speed / 1024.0), obj->e, 1);
}
OBJ(uptime_short) {
format_seconds_short(p, p_max_size,
@ -6959,6 +6990,8 @@ void clean_up(void)
free (specials);
specials=NULL;
}
clear_diskio_stats();
}
static int string_to_bool(const char *s)
@ -7008,6 +7041,7 @@ static void set_default_configurations(void)
info.memmax = 0;
top_cpu = 0;
cpu_separate = 0;
short_units = 0;
top_mem = 0;
#ifdef MPD
strcpy(info.mpd.host, "localhost");
@ -7032,7 +7066,7 @@ static void set_default_configurations(void)
info.xmms2.url = NULL;
info.xmms2.status = NULL;
#endif
use_spacer = 0;
use_spacer = NO_SPACER;
#ifdef X11
out_to_console = 0;
#else
@ -7377,7 +7411,30 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
out_to_console = string_to_bool(value);
}
CONF("use_spacer") {
use_spacer = string_to_bool(value);
if (value) {
if (strcasecmp(value, "left") == 0) {
use_spacer = LEFT_SPACER;
} else if (strcasecmp(value, "right") == 0) {
use_spacer = RIGHT_SPACER;
} else if (strcasecmp(value, "none") == 0) {
use_spacer = NO_SPACER;
} else {
use_spacer = string_to_bool(value);
ERR("use_spacer should have an argument of left, right, or"
" none. '%s' seems to be some form of '%s', so"
" defaulting to %s.", value,
use_spacer ? "true" : "false",
use_spacer ? "right" : "none");
if (use_spacer) {
use_spacer = RIGHT_SPACER;
} else {
use_spacer = NO_SPACER;
}
}
} else {
ERR("use_spacer should have an argument. Defaulting to right.");
use_spacer = RIGHT_SPACER;
}
}
#ifdef X11
#ifdef XFT
@ -7474,6 +7531,9 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
CONF("top_cpu_separate") {
cpu_separate = string_to_bool(value);
}
CONF("short_units") {
short_units = string_to_bool(value);
}
CONF("pad_percents") {
pad_percents = atoi(value);
}

View File

@ -141,6 +141,8 @@ struct fs_stat {
long long free;
};
#include "diskio.h"
struct mail_s { // for imap and pop3
unsigned long unseen;
unsigned long messages;
@ -373,6 +375,8 @@ int top_mem;
int use_spacer;
enum spacer_opts { NO_SPACER = 0, LEFT_SPACER, RIGHT_SPACER };
char tmpstring1[TEXT_BUFFER_SIZE];
char tmpstring2[TEXT_BUFFER_SIZE];
@ -462,6 +466,7 @@ long get_x11_color(const char *);
#endif /* X11 */
int cpu_separate;
int short_units;
/* in common.c */

75
src/diskio.c Normal file
View File

@ -0,0 +1,75 @@
/*
* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
* All code written since the fork of torsmo is licensed under the GPL
*
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
#include <limits.h>
#include "conky.h"
static struct diskio_stat diskio_stats_[MAX_DISKIO_STATS];
struct diskio_stat *diskio_stats = diskio_stats_;
void clear_diskio_stats()
{
unsigned i;
for(i = 0; i < MAX_DISKIO_STATS; i++) {
if (diskio_stats[i].dev) {
free(diskio_stats[i].dev);
diskio_stats[i].dev = 0;
}
}
}
struct diskio_stat *prepare_diskio_stat(const char *s)
{
struct diskio_stat *new = 0;
unsigned i;
/* lookup existing or get new */
for (i = 0; i < MAX_DISKIO_STATS; i++) {
if (diskio_stats[i].dev) {
if (strcmp(diskio_stats[i].dev, s) == 0) {
return &diskio_stats[i];
}
} else {
new = &diskio_stats[i];
break;
}
}
/* new dev */
if (!new) {
ERR("too many diskio stats");
return 0;
}
new->dev = strdup(s);
new->current = 0;
new->current_read = 0;
new ->current_write = 0;
new->last = UINT_MAX;
new->last_read = UINT_MAX;
new->last_write = UINT_MAX;
return new;
}

17
src/diskio.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef DISKIO_H_
#define DISKIO_H_
struct diskio_stat {
char *dev;
unsigned int current, current_read, current_write, last, last_read,
last_write;
};
#define MAX_DISKIO_STATS 64
struct diskio_stat *diskio_stats;
struct diskio_stat *prepare_diskio_stat(const char *s);
void clear_diskio_stats();
#endif /* DISKIO_H_ */

View File

@ -674,9 +674,7 @@ cleanup:
void
update_diskio()
{
int devs_count,
num_selected,
num_selections;
int devs_count, num_selected, num_selections, i;
struct device_selection *dev_select = NULL;
long select_generation;
int dn;
@ -704,6 +702,35 @@ update_diskio()
diskio_current += dev->bytes[DEVSTAT_READ] +
dev->bytes[DEVSTAT_WRITE];
for (i = 0; i < MAX_DISKIO_STATS; i++) {
if (diskio_stats[i].dev && strcmp(dev_select[dn].device_name,
diskio_stats[i].dev) == 0) {
diskio_stats[i].current =
(dev->bytes[DEVSTAT_READ] + dev->bytes[DEVSTAT_WRITE] -
diskio_stats[i].last) / 1024;
diskio_stats[i].current_read = (dev->bytes[DEVSTAT_READ] -
diskio_stats[i].last_read) / 1024;
diskio_stats[i].current_write = (dev->bytes[DEVSTAT_WRITE] -
diskio_stats[i].last_write) / 1024;
if (dev->bytes[DEVSTAT_READ] +
dev->bytes[DEVSTAT_WRITE] < diskio_stats[i].last) {
diskio_stats[i].current = 0;
}
if (dev->bytes[DEVSTAT_READ] < diskio_stats[i].last_read) {
diskio_stats[i].current_read = 0;
diskio_stats[i].current = diskio_stats[i].current_write;
}
if (writes < diskio_stats[i].last_write) {
diskio_stats[i].current_write = 0;
diskio_stats[i].current = diskio_stats[i].current_read;
}
diskio_stats[i].last = dev->bytes[DEVSTAT_READ] +
dev->bytes[DEVSTAT_WRITE];
diskio_stats[i].last_read = dev->bytes[DEVSTAT_READ];
diskio_stats[i].last_write = dev->bytes[DEVSTAT_WRITE];
}
}
}
free(dev_select);

View File

@ -1699,8 +1699,8 @@ void update_diskio()
FILE* fp;
static int rep=0;
char buf[512];
int major, minor;
char buf[512], devbuf[64];
int major, minor, i;
unsigned int current = 0;
unsigned int current_read = 0;
unsigned int current_write = 0;
@ -1717,19 +1717,49 @@ void update_diskio()
*/
while (!feof(fp)) {
fgets(buf, 512, fp);
col_count = sscanf(buf, "%u %u %*s %*u %*u %u %*u %*u %*u %u",
&major, &minor, &reads, &writes);
col_count = sscanf(buf, "%u %u %s %*u %*u %u %*u %*u %*u %u",
&major, &minor, devbuf, &reads, &writes);
/* ignore subdevices (they have only 3 matching entries in their line)
* and virtual devices (LVM, network block devices, RAM disks, Loopback)
*
* XXX ignore devices which are part of a SW RAID (MD_MAJOR)
*/
if (col_count > 3 &&
major != LVM_BLK_MAJOR && major != NBD_MAJOR &&
if (col_count == 5 && major != LVM_BLK_MAJOR && major != NBD_MAJOR &&
major != RAMDISK_MAJOR && major != LOOP_MAJOR) {
current += reads + writes;
current_read += reads;
current_write += writes;
} else {
col_count = sscanf(buf, "%u %u %s %*u %u %*u %u",
&major, &minor, devbuf, &reads, &writes);
if (col_count != 5) {
continue;
}
}
for (i = 0; i < MAX_DISKIO_STATS; i++) {
if (diskio_stats[i].dev &&
strcmp(devbuf, diskio_stats[i].dev) == 0) {
diskio_stats[i].current =
(reads + writes - diskio_stats[i].last) / 2;
diskio_stats[i].current_read =
(reads - diskio_stats[i].last_read) / 2;
diskio_stats[i].current_write =
(writes - diskio_stats[i].last_write) / 2;
if (reads + writes < diskio_stats[i].last) {
diskio_stats[i].current = 0;
}
if (reads < diskio_stats[i].last_read) {
diskio_stats[i].current_read = 0;
diskio_stats[i].current = diskio_stats[i].current_write;
}
if (writes < diskio_stats[i].last_write) {
diskio_stats[i].current_write = 0;
diskio_stats[i].current = diskio_stats[i].current_read;
}
diskio_stats[i].last = reads + writes;
diskio_stats[i].last_read = reads;
diskio_stats[i].last_write = writes;
}
}
}