Allow <interval> to be successfully sscanf'd no matter the locale for the

decimal symbol.  Fixes https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=2880 (again).

#BACKPORT(1.8)

svn path=/trunk/; revision=45770
This commit is contained in:
Chris Maynard 2012-10-24 17:46:16 +00:00
parent b8e5c94167
commit bc8e520439
1 changed files with 129 additions and 118 deletions

View File

@ -36,14 +36,14 @@
#include "globals.h"
#define CALC_TYPE_FRAMES 0
#define CALC_TYPE_BYTES 1
#define CALC_TYPE_FRAMES_AND_BYTES 2
#define CALC_TYPE_COUNT 3
#define CALC_TYPE_SUM 4
#define CALC_TYPE_MIN 5
#define CALC_TYPE_MAX 6
#define CALC_TYPE_AVG 7
#define CALC_TYPE_LOAD 8
#define CALC_TYPE_BYTES 1
#define CALC_TYPE_FRAMES_AND_BYTES 2
#define CALC_TYPE_COUNT 3
#define CALC_TYPE_SUM 4
#define CALC_TYPE_MIN 5
#define CALC_TYPE_MAX 6
#define CALC_TYPE_AVG 7
#define CALC_TYPE_LOAD 8
typedef struct {
const char *func_name;
@ -102,7 +102,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
GPtrArray *gp;
guint i;
int ftype;
mit = (io_stat_item_t *) arg;
parent = mit->parent;
relative_time = (guint64)((pinfo->fd->rel_ts.secs*1000000) + ((pinfo->fd->rel_ts.nsecs+500)/1000));
@ -120,7 +120,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
}
/* If we have moved into a new interval (row), create a new io_stat_item_t struct for every interval
* between the last struct and this one. If an item was not found in a previous interval, an empty
* between the last struct and this one. If an item was not found in a previous interval, an empty
* struct will be created for it. */
rt = relative_time;
while (rt >= it->time + parent->interval) {
@ -182,7 +182,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
it->counter += (gint64)fvalue_get_integer64(&((field_info *)gp->pdata[i])->value);
break;
case FT_FLOAT:
it->float_counter +=
it->float_counter +=
(gfloat)fvalue_get_floating(&((field_info *)gp->pdata[i])->value);
break;
case FT_DOUBLE:
@ -242,7 +242,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
val = fvalue_get_integer64(&((field_info *)gp->pdata[i])->value);
if((it->frames==1 && i==0) || ((gint64)val < (gint64)it->counter)) {
it->counter=val;
}
}
break;
case FT_FLOAT:
float_val=(gfloat)fvalue_get_floating(&((field_info *)gp->pdata[i])->value);
@ -254,7 +254,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
double_val=fvalue_get_floating(&((field_info *)gp->pdata[i])->value);
if((it->frames==1 && i==0) || (double_val < it->double_counter)) {
it->double_counter=double_val;
}
}
break;
case FT_RELATIVE_TIME:
new_time = (nstime_t *)fvalue_get(&((field_info *)gp->pdata[i])->value);
@ -294,7 +294,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
break;
case FT_UINT64:
val = fvalue_get_integer64(&((field_info *)gp->pdata[i])->value);
if(val > it->counter)
if(val > it->counter)
it->counter=val;
break;
case FT_INT8:
@ -302,12 +302,12 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
case FT_INT24:
case FT_INT32:
val = fvalue_get_sinteger(&((field_info *)gp->pdata[i])->value);
if((gint32)val > (gint32)it->counter)
if((gint32)val > (gint32)it->counter)
it->counter=val;
break;
case FT_INT64:
val = fvalue_get_integer64(&((field_info *)gp->pdata[i])->value);
if ((gint64)val > (gint64)it->counter)
if ((gint64)val > (gint64)it->counter)
it->counter=val;
break;
case FT_FLOAT:
@ -341,7 +341,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
gp=proto_get_finfo_ptr_array(edt->tree, it->hf_index);
if(gp){
guint64 val;
ftype=proto_registrar_get_ftype(it->hf_index);
for(i=0;i<gp->len;i++){
it->num++;
@ -420,21 +420,21 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
}
break;
}
/* Store the highest value for this item in order to determine the width of each stat column.
/* Store the highest value for this item in order to determine the width of each stat column.
* For real numbers we only need to know its magnitude (the value to the left of the decimal point
* so round it up before storing it as an integer in max_vals. For AVG of RELATIVE_TIME fields,
* calc the average, round it to the next second and store the seconds. For all other calc types
* of RELATIVE_TIME fields, store the counters without modification.
* of RELATIVE_TIME fields, store the counters without modification.
* fields. */
switch(it->calc_type) {
case CALC_TYPE_FRAMES:
case CALC_TYPE_FRAMES_AND_BYTES:
parent->max_frame[it->colnum] =
parent->max_frame[it->colnum] =
MAX(parent->max_frame[it->colnum], it->frames);
if (it->calc_type==CALC_TYPE_FRAMES_AND_BYTES)
parent->max_vals[it->colnum] =
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum], it->counter);
case CALC_TYPE_BYTES:
case CALC_TYPE_COUNT:
case CALC_TYPE_LOAD:
@ -446,20 +446,20 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
ftype=proto_registrar_get_ftype(it->hf_index);
switch(ftype) {
case FT_FLOAT:
parent->max_vals[it->colnum] =
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum], (guint64)(it->float_counter+0.5));
break;
case FT_DOUBLE:
parent->max_vals[it->colnum] =
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum],(guint64)(it->double_counter+0.5));
break;
case FT_RELATIVE_TIME:
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum], it->counter);
break;
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum], it->counter);
break;
default:
/* UINT16-64 and INT8-64 */
parent->max_vals[it->colnum] =
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum], it->counter);
break;
}
@ -470,20 +470,20 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
ftype=proto_registrar_get_ftype(it->hf_index);
switch(ftype) {
case FT_FLOAT:
parent->max_vals[it->colnum] =
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum], (guint64)it->float_counter/it->num);
break;
case FT_DOUBLE:
parent->max_vals[it->colnum] =
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum],(guint64)it->double_counter/it->num);
break;
case FT_RELATIVE_TIME:
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum], ((it->counter/it->num) + 500000000) / NANOSECS_PER_SEC);
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum], ((it->counter/it->num) + 500000000) / NANOSECS_PER_SEC);
break;
default:
/* UINT16-64 and INT8-64 */
parent->max_vals[it->colnum] =
parent->max_vals[it->colnum] =
MAX(parent->max_vals[it->colnum], it->counter/it->num);
break;
}
@ -491,21 +491,21 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
return TRUE;
}
static int
static int
magnitude (guint64 val, int max_w)
{
int i, mag=0;
for (i=0; i<max_w; i++) {
mag++;
if ((val /= 10)==0)
break;
if ((val /= 10)==0)
break;
}
return(mag);
}
/*
* Print the calc_type_table[] function label centered in the column header.
/*
* Print the calc_type_table[] function label centered in the column header.
*/
static void
printcenter (const char *label, int lenval, int numpad)
@ -515,11 +515,11 @@ printcenter (const char *label, int lenval, int numpad)
len = (int) (strlen(spaces)) - (((lenval-lenlab) / 2) + numpad);
if (len > 0 && len < 6) {
spaces_ptr = &spaces[len];
spaces_ptr = &spaces[len];
if ((lenval-lenlab)%2==0) {
printf("%s%s%s|", spaces_ptr, label, spaces_ptr);
} else {
printf("%s%s%s|", spaces_ptr-1, label, spaces_ptr);
printf("%s%s%s|", spaces_ptr-1, label, spaces_ptr);
}
} else if (len > 0 && len <= 15) {
printf("%s|", label);
@ -546,7 +546,7 @@ iostat_draw(void *arg)
io_stat_item_t *mit, **stat_cols, *item, **item_in_column;
gboolean last_row=FALSE;
io_stat_t *iot;
column_width *col_w;
column_width *col_w;
struct tm * tm_time;
time_t the_time;
@ -574,19 +574,19 @@ iostat_draw(void *arg)
/* Calc the capture duration's magnitude (dur_mag) */
dur_secs = (int)duration/1000000;
dur_mag = magnitude((guint64)dur_secs, 5);
g_snprintf(dur_mag_s, 3, "%u", dur_mag);
g_snprintf(dur_mag_s, 3, "%u", dur_mag);
/* Calc the interval's magnitude */
invl_mag = magnitude((guint64)interval/1000000, 5);
invl_mag = magnitude((guint64)interval/1000000, 5);
/* Set or get the interval precision */
if (interval==duration) {
/*
/*
* An interval arg of 0 or an interval size exceeding the capture duration was specified.
* Set the decimal precision of duration based on its magnitude. */
if (dur_mag >= 2)
invl_prec = 1;
else if (dur_mag==1)
else if (dur_mag==1)
invl_prec = 3;
else
invl_prec = 6;
@ -602,7 +602,7 @@ iostat_draw(void *arg)
for (i=0; i<invl_prec; i++)
dv /= 10;
duration = duration + (5*(dv/10));
if (iot->interval==G_MAXINT32)
if (iot->interval==G_MAXINT32)
interval = duration;
/* Recalc the dur_mag in case rounding has increased its magnitude */
@ -610,18 +610,18 @@ iostat_draw(void *arg)
dur_mag = magnitude((guint64)dur_secs, 5);
/* Calc the width of the time interval column (incl borders and padding). */
if (invl_prec==0)
if (invl_prec==0)
invl_col_w = (2*dur_mag) + 8;
else
invl_col_w = (2*dur_mag) + (2*invl_prec) + 10;
/* Update the width of the time interval column for "-t ad" */
if (timestamp_get_type()==TS_ABSOLUTE_WITH_DATE)
/* Update the width of the time interval column for "-t ad" */
if (timestamp_get_type()==TS_ABSOLUTE_WITH_DATE)
invl_col_w = MAX(invl_col_w, 23);
else
invl_col_w = MAX(invl_col_w, 12);
else
invl_col_w = MAX(invl_col_w, 12);
borderlen = MAX(borderlen, invl_col_w);
borderlen = MAX(borderlen, invl_col_w);
/* Calc the total width of each row in the stats table and build the printf format string for each
* column based on its field type, width, and name length.
@ -645,9 +645,9 @@ iostat_draw(void *arg)
g_snprintf(fr_mag_s, 3, "%u", fr_mag);
if (type==CALC_TYPE_FRAMES) {
fmt = g_strconcat(" %", fr_mag_s, "u |", NULL);
} else {
/* CALC_TYPE_FRAMES_AND_BYTES
fmt = g_strconcat(" %", fr_mag_s, "u |", NULL);
} else {
/* CALC_TYPE_FRAMES_AND_BYTES
*/
val_mag = magnitude(iot->max_vals[j], 15);
val_mag = MAX(5, val_mag);
@ -670,10 +670,10 @@ iostat_draw(void *arg)
g_snprintf(val_mag_s, 3, "%u", val_mag);
fmt = g_strconcat(" %", val_mag_s, G_GINT64_MODIFIER, "u |", NULL);
break;
default:
ftype = proto_registrar_get_ftype(stat_cols[j]->hf_index);
switch (ftype) {
switch (ftype) {
case FT_FLOAT:
case FT_DOUBLE:
val_mag = magnitude(iot->max_vals[j], 15);
@ -682,7 +682,7 @@ iostat_draw(void *arg)
col_w[j].val = val_mag + 7;
break;
case FT_RELATIVE_TIME:
/* Convert FT_RELATIVE_TIME field to seconds
/* Convert FT_RELATIVE_TIME field to seconds
* CALC_TYPE_LOAD was already converted in iostat_packet() ) */
if (type==CALC_TYPE_LOAD) {
iot->max_vals[j] /= interval;
@ -693,14 +693,14 @@ iostat_draw(void *arg)
g_snprintf(val_mag_s, 3, "%u", val_mag);
fmt = g_strconcat(" %", val_mag_s, "u.%06u |", NULL);
col_w[j].val = val_mag + 7;
break;
break;
default:
val_mag = magnitude(iot->max_vals[j], 15);
val_mag = MAX(namelen, val_mag);
col_w[j].val = val_mag;
g_snprintf(val_mag_s, 3, "%u", val_mag);
switch (ftype) {
case FT_UINT8:
case FT_UINT16:
@ -708,7 +708,7 @@ iostat_draw(void *arg)
case FT_UINT32:
case FT_UINT64:
fmt = g_strconcat(" %", val_mag_s, G_GINT64_MODIFIER, "u |", NULL);
break;
break;
case FT_INT8:
case FT_INT16:
case FT_INT24:
@ -720,11 +720,11 @@ iostat_draw(void *arg)
} /* End of ftype switch */
} /* End of calc_type switch */
tabrow_w += col_w[j].val + 3;
if (fmt)
if (fmt)
fmts[j] = fmt;
} /* End of for loop (columns) */
borderlen = MAX(borderlen, tabrow_w);
borderlen = MAX(borderlen, tabrow_w);
/* Calc the max width of the list of filters. */
maxfltr_w = 0;
@ -739,7 +739,7 @@ iostat_draw(void *arg)
/* The stat table is not wrapped (by tshark) but filter is wrapped at the width of the stats table
* (which currently = borderlen); however, if the filter width exceeds the table width and the
* table width is less than 102 bytes, set borderlen to the lesser of the max filter width and 102.
* The filters will wrap at the lesser of borderlen-2 and the last space in the filter.
* The filters will wrap at the lesser of borderlen-2 and the last space in the filter.
* NOTE: 102 is the typical size of a user window when the font is fixed width (e.g., COURIER 10).
* XXX: A pref could be added to change the max width from the default size of 102. */
if (maxfltr_w > borderlen && borderlen < 102)
@ -747,27 +747,27 @@ iostat_draw(void *arg)
/* Prevent double right border by adding a space */
if (borderlen-tabrow_w==1)
borderlen++;
borderlen++;
/* Display the top border */
printf("\n");
for (i=0; i<borderlen; i++)
printf("=");
spaces = (char*) g_malloc(borderlen+1);
for (i=0; i<borderlen; i++)
for (i=0; i<borderlen; i++)
spaces[i] = ' ';
spaces[borderlen] = '\0';
spaces_s = &spaces[16];
printf("\n| IO Statistics%s|\n", spaces_s);
spaces_s = &spaces[2];
printf("|%s|\n", spaces_s);
g_snprintf(invl_mag_s, 3, "%u", invl_mag);
if (invl_prec > 0) {
g_snprintf(invl_prec_s, 3, "%u", invl_prec);
invl_fmt = g_strconcat("%", invl_mag_s, "u.%0", invl_prec_s, "u", NULL);
g_snprintf(invl_prec_s, 3, "%u", invl_prec);
invl_fmt = g_strconcat("%", invl_mag_s, "u.%0", invl_prec_s, "u", NULL);
if (interval==duration) {
full_fmt = g_strconcat("| Interval size: ", invl_fmt, " secs (dur)%s", NULL);
spaces_s = &spaces[30+invl_mag+invl_prec];
@ -786,24 +786,24 @@ iostat_draw(void *arg)
g_free(invl_fmt);
g_free(full_fmt);
if (invl_prec > 0)
if (invl_prec > 0)
invl_fmt = g_strconcat("%", dur_mag_s, "u.%0", invl_prec_s, "u", NULL);
else
else
invl_fmt = g_strconcat("%", dur_mag_s, "u", NULL);
/* Display the list of filters and their column numbers vertically */
printf("|\n| Col");
for(j=0; j<num_cols; j++){
printf((j==0 ? "%2u: " : "| %2u: "), j+1);
if (!iot->filters[j] || (iot->filters[j]==0)) {
/*
if (!iot->filters[j] || (iot->filters[j]==0)) {
/*
* An empty (no filter) comma field was specified */
spaces_s = &spaces[16 + 10];
printf("Frames and bytes%s|\n", spaces_s);
} else {
filter = iot->filters[j];
len_filt = (int) strlen(filter);
/* If the width of the widest filter exceeds the width of the stat table, borderlen has
* been set to 102 bytes above and filters wider than 102 will wrap at 91 bytes. */
if (len_filt+11 <= borderlen) {
@ -818,11 +818,11 @@ iostat_draw(void *arg)
const gchar *pos;
gsize len;
int next_start, max_w=borderlen-11;
do {
if (len_filt > max_w) {
sfilter1 = g_strndup( (gchar *) filter, (gsize) max_w);
/*
/*
* Find the pos of the last space in sfilter1. If a space is found, set
* sfilter2 to the string prior to that space and print it; otherwise, wrap
* the filter at max_w. */
@ -846,7 +846,7 @@ iostat_draw(void *arg)
printf("%s%s|\n", filter, &spaces[((int)strlen(filter))+10]);
break;
}
} while (1);
} while (1);
}
}
}
@ -865,11 +865,11 @@ iostat_draw(void *arg)
for(j=0; j<num_cols; j++) {
item = stat_cols[j];
if(item->calc_type==CALC_TYPE_FRAMES_AND_BYTES)
spaces_s = &spaces[borderlen - (col_w[j].fr + col_w[j].val)] - 3;
spaces_s = &spaces[borderlen - (col_w[j].fr + col_w[j].val)] - 3;
else if (item->calc_type==CALC_TYPE_FRAMES)
spaces_s = &spaces[borderlen - col_w[j].fr];
spaces_s = &spaces[borderlen - col_w[j].fr];
else
spaces_s = &spaces[borderlen - col_w[j].val];
spaces_s = &spaces[borderlen - col_w[j].val];
printf("%-2u%s|", j+1, spaces_s);
}
@ -877,15 +877,15 @@ iostat_draw(void *arg)
filler_s = &spaces[tabrow_w+1];
printf("%s|", filler_s);
}
k = 11;
k = 11;
switch (timestamp_get_type()) {
case TS_ABSOLUTE:
printf("\n| Time ");
break;
case TS_ABSOLUTE_WITH_DATE:
printf("\n| Date and time");
k = 16;
k = 16;
break;
case TS_RELATIVE:
case TS_NOT_SET:
@ -895,7 +895,7 @@ iostat_draw(void *arg)
break;
}
spaces_s = &spaces[borderlen-(invl_col_w-k)];
spaces_s = &spaces[borderlen-(invl_col_w-k)];
printf("%s|", spaces_s);
/* Display the stat label in each column */
@ -932,7 +932,7 @@ iostat_draw(void *arg)
item_in_column[j] = stat_cols[j];
}
/* Display the table values
/* Display the table values
*
* The outer loop is for time interval rows and the inner loop is for stat column items.*/
for (i=0; i<num_rows; i++) {
@ -952,14 +952,14 @@ iostat_draw(void *arg)
tm_time = localtime(&the_time);
/* Display the interval for this row */
switch (timestamp_get_type()) {
switch (timestamp_get_type()) {
case TS_ABSOLUTE:
printf("| %02d:%02d:%02d |",
tm_time->tm_hour,
tm_time->tm_min,
tm_time->tm_sec);
break;
case TS_ABSOLUTE_WITH_DATE:
printf("| %04d-%02d-%02d %02d:%02d:%02d |",
tm_time->tm_year + 1900,
@ -969,7 +969,7 @@ iostat_draw(void *arg)
tm_time->tm_min,
tm_time->tm_sec);
break;
case TS_RELATIVE:
case TS_NOT_SET:
@ -996,7 +996,7 @@ iostat_draw(void *arg)
/* Display stat values in each column for this row */
for (j=0; j<num_cols; j++) {
fmt = fmts[j];
item = item_in_column[j];
item = item_in_column[j];
if (item) {
switch(item->calc_type) {
@ -1061,8 +1061,8 @@ iostat_draw(void *arg)
case FT_RELATIVE_TIME:
if (!last_row) {
printf(fmt,
(int) (item->counter/interval),
(int)((item->counter%interval)*1000000 / interval));
(int) (item->counter/interval),
(int)((item->counter%interval)*1000000 / interval));
} else {
printf(fmt,
(int) (item->counter/(invl_end-t)),
@ -1077,7 +1077,7 @@ iostat_draw(void *arg)
if (fmt)
g_free(fmt);
} else {
item_in_column[j] = item_in_column[j]->next;
item_in_column[j] = item_in_column[j]->next;
}
} else {
printf(fmt, (guint64)0);
@ -1087,7 +1087,7 @@ iostat_draw(void *arg)
printf("%s|", filler_s);
printf("\n");
t += interval;
}
for(i=0;i<borderlen;i++){
printf("=");
@ -1141,14 +1141,14 @@ register_io_tap(io_stat_t *io, int i, const char *filter)
p=filter+namelen+1;
parenp=strchr(p, ')');
if(!parenp){
fprintf(stderr,
fprintf(stderr,
"\ntshark: Closing parenthesis missing from calculated expression.\n");
exit(10);
}
if(io->items[i].calc_type==CALC_TYPE_FRAMES || io->items[i].calc_type==CALC_TYPE_BYTES){
if(parenp!=p) {
fprintf(stderr,
fprintf(stderr,
"\ntshark: %s does not require or allow a field name within the parens.\n",
calc_type_table[j].func_name);
exit(10);
@ -1274,13 +1274,29 @@ iostat_init(const char *optarg, void* userdata _U_)
gdouble interval_float;
guint32 idx=0, i;
io_stat_t *io;
const gchar *filters=NULL, *str, *pos;
const gchar *filters, *str, *pos;
if (sscanf(optarg, "io,stat,%lf,%n", &interval_float, (int *)&idx)==0) {
fprintf(stderr, "\ntshark: invalid \"-z io,stat,<interval>[,<filter>]\" argument\n");
if ((*(optarg+(strlen(optarg)-1)) == ',') ||
(sscanf(optarg, "io,stat,%lf%n", &interval_float, (int *)&idx) != 1) ||
(idx < 8)) {
fprintf(stderr, "\ntshark: invalid \"-z io,stat,<interval>[,<filter>][,<filter>]...\" argument\n");
exit(1);
}
filters=optarg+idx;
if (*filters) {
if (*filters != ',') {
/* For locale's that use ',' instead of '.', the comma might
* have been consumed during the floating point conversion. */
--filters;
if (*filters != ',') {
fprintf(stderr, "\ntshark: invalid \"-z io,stat,<interval>[,<filter>][,<filter>]...\" argument\n");
exit(1);
}
}
} else
filters=NULL;
switch (timestamp_get_type()) {
case TS_DELTA:
case TS_DELTA_DIS:
@ -1289,11 +1305,11 @@ iostat_init(const char *optarg, void* userdata _U_)
case TS_UTC_WITH_DATE:
fprintf(stderr, "\ntshark: invalid -t operand. io,stat only supports -t <r|a|ad>\n");
exit(1);
default:
break;
default:
break;
}
io = (io_stat_t *) g_malloc(sizeof(io_stat_t));
io = (io_stat_t *) g_malloc(sizeof(io_stat_t));
/* If interval is 0, calculate statistics over the whole file by setting the interval to
* G_MAXINT32 */
@ -1306,7 +1322,7 @@ iostat_init(const char *optarg, void* userdata _U_)
/*
* Determine what interval precision the user has specified */
io->invl_prec = 6;
for (i=10; i<10000000; i*=10) {
for (i=10; i<10000000; i*=10) {
if (io->interval%i > 0)
break;
io->invl_prec--;
@ -1322,17 +1338,12 @@ iostat_init(const char *optarg, void* userdata _U_)
io->num_cols = 1;
io->start_time=0;
if (idx) {
filters = optarg + idx;
if (strlen(filters) > 0 ) {
str = filters;
while((str = strchr(str, ','))) {
io->num_cols++;
str++;
}
if (filters && (*filters != '\0')) {
str = filters;
while((str = strchr(str, ','))) {
io->num_cols++;
str++;
}
} else {
filters=NULL;
}
io->items = (io_stat_item_t *) g_malloc(sizeof(io_stat_item_t) * io->num_cols);
@ -1343,7 +1354,7 @@ iostat_init(const char *optarg, void* userdata _U_)
for (i=0; i<io->num_cols; i++) {
io->max_vals[i] = 0;
io->max_frame[i] = 0;
}
}
/* Register a tap listener for each filter */
if((!filters) || (filters[0]==0)) {