cnfsstat rounding trouble

Christoph Biedl cbiedl at
Sun May 23 13:55:23 UTC 2004

I've seen that trouble a lot in the last year: The rounding of the
cnfsstat output fails and always gives zeros, e.g.

| Class INTERNAL  for groups matching "internal.*"
|  Buffer 14_01, size:  16.0 MBytes, position:  14.0 MBytes  6.00 cycles
                                                   ^           ^^
which is probably wrong for "position" and obviously wrong for "cycles".

This happens with Debian sarge (INN 2.4.1, perl 5.8).
This does not happen with Debian stable (INN 2.3.x or INN 2.4.1 compiled
from sources, perl 5.6)
This _might_ have also happened more than one year ago with a terribly
deconfigured Slackware running INN 2.3.x and perl 5.8.

Trying to reproduce this error didn't succeed however I'm quite sure that
this problem ist related to a minor change between Perl 5.6 and 5.8.

What actually happens:
Looking at cnfsstat line 290 (and similar places)
|     printf("  %.2f cycles\n", $cyclenum + $free/$len);
the division $free/$len always results in 0 since $free <= $len and perl
appearently uses integer division.

How to fix:
The C-style make-me-double '(1.0 * $free)/(1.0 * $len)' does not help, a
workaround is to eval the variables before doing the computations:

--- /usr/lib/news/bin/cnfsstat  2004-05-22 22:51:24.000000000 +0200
+++ /tmp/cnfsstat       2004-05-23 15:38:36.000000000 +0200
@@ -275,6 +275,8 @@
     my ($name, $len, $free, $update, $cyclenum, $oldart) =
+    $free = eval ($free);
+    $len = eval ($len);
     if ($use_syslog) {
        ($name) = split(/\s/, $name);
        $name =~ s/\0//g;
@@ -319,6 +321,7 @@
 sub human_readable {
     my ($val, $digits) = @_;
     $val =~ s/\+//;
+    $val = eval ($val);
     my @name = ("kBytes", "MBytes", "GBytes", "TBytes");
     my $base = 1024;

This is probably not the best way to solve it.  I'd also be glad to learn
what really goes wrong.


More information about the inn-workers mailing list