I wanted to have
 $ systat ifstat 1

to print meaningful numbers to measure live network throughput.
With these two features you are now able to see sth like "MBit/s"
in the ifstat view.

"B" converts to Bits
"," activates the thousands separator.

Comments? OKs?
 
Index: engine.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/engine.c,v
retrieving revision 1.13
diff -p -u -p -u -r1.13 engine.c
--- engine.c    19 Jul 2010 04:41:28 -0000      1.13
+++ engine.c    15 Mar 2011 08:34:00 -0000
@@ -69,6 +69,7 @@ volatile sig_atomic_t gotsig_resize = 0;
 volatile sig_atomic_t gotsig_alarm = 0;
 int need_update = 0;
 int need_sort = 0;
+int separate_thousands = 0;
 
 SCREEN *screen;
 
@@ -134,7 +135,60 @@ tbprintf(char *format, ...)
                tb_ptr += len;
                tb_len -= len;
        }
-       
+
+       return len;
+}
+
+int
+tbprintft(char *format, ...)
+       GCC_PRINTFLIKE(1,2)       /* defined in curses.h */
+{
+       int len;
+       va_list arg;
+       char buf[MAX_LINE_BUF];
+
+       if (tb_ptr == NULL || tb_len <= 0)
+               return 0;
+
+       va_start(arg, format);
+       len = vsnprintf(buf, tb_len, format, arg);
+       va_end(arg);
+
+       if (len > tb_len)
+               tb_end();
+       else if (len > 0) {
+               int d, s;
+               int digits, curdigit;
+
+               if (!separate_thousands) {
+                       strlcpy(tb_ptr, buf, tb_len);
+                       return len;
+               }
+
+               /* count until we hit a non digit. (e.g. the prefix) */
+               for (digits = 0; digits < len; digits++)
+                       if (!isdigit(buf[digits]))
+                               break;
+
+               curdigit = digits;
+               d = s = 0;
+               /* insert thousands separators while copying */
+               while (curdigit && d < tb_len) {
+                       if (curdigit < digits && curdigit % 3 == 0)
+                               tb_ptr[d++] = ',';
+                       tb_ptr[d++] = buf[s++];
+                       curdigit--;
+               }
+               /* copy the remaining non-digits */
+               while (len > digits && d < tb_len) {
+                       tb_ptr[d++] = buf[s++];
+                       digits++;
+               }
+               tb_ptr[d] = '\0';
+               tb_ptr += d;
+               tb_len -= d;
+               len = d;
+       }
        return len;
 }
 
@@ -672,33 +726,33 @@ print_fld_sdiv(field_def *fld, u_int64_t
                return;
 
        tb_start();
-       if (tbprintf("%llu", size) <= len)
+       if (tbprintft("%llu", size) <= len)
                goto ok;
 
        tb_start();
        size /= d;
-       if (tbprintf("%lluK", size) <= len)
+       if (tbprintft("%lluK", size) <= len)
                goto ok;
        if (size == 0)
                goto err;
 
        tb_start();
        size /= d;
-       if (tbprintf("%lluM", size) <= len)
+       if (tbprintft("%lluM", size) <= len)
                goto ok;
        if (size == 0)
                goto err;
 
        tb_start();
        size /= d;
-       if (tbprintf("%lluG", size) <= len)
+       if (tbprintft("%lluG", size) <= len)
                goto ok;
        if (size == 0)
                goto err;
 
        tb_start();
        size /= d;
-       if (tbprintf("%lluT", size) <= len)
+       if (tbprintft("%lluT", size) <= len)
                goto ok;
        
 err:
@@ -729,33 +783,33 @@ print_fld_ssdiv(field_def *fld, int64_t 
                return;
 
        tb_start();
-       if (tbprintf("%lld", size) <= len)
+       if (tbprintft("%lld", size) <= len)
                goto ok;
 
        tb_start();
        size /= d;
-       if (tbprintf("%lldK", size) <= len)
+       if (tbprintft("%lldK", size) <= len)
                goto ok;
        if (size == 0)
                goto err;
 
        tb_start();
        size /= d;
-       if (tbprintf("%lldM", size) <= len)
+       if (tbprintft("%lldM", size) <= len)
                goto ok;
        if (size == 0)
                goto err;
 
        tb_start();
        size /= d;
-       if (tbprintf("%lldG", size) <= len)
+       if (tbprintft("%lldG", size) <= len)
                goto ok;
        if (size == 0)
                goto err;
 
        tb_start();
        size /= d;
-       if (tbprintf("%lldT", size) <= len)
+       if (tbprintft("%lldT", size) <= len)
                goto ok;
 
 err:
@@ -806,7 +860,7 @@ print_fld_uint(field_def *fld, unsigned 
                return;
 
        tb_start();
-       if (tbprintf("%u", size) > len)
+       if (tbprintft("%u", size) > len)
                print_fld_str(fld, "*");
        else
                print_fld_tb(fld);
Index: engine.h
===================================================================
RCS file: /cvs/src/usr.bin/systat/engine.h,v
retrieving revision 1.6
diff -p -u -p -u -r1.6 engine.h
--- engine.h    16 Jul 2010 05:22:48 -0000      1.6
+++ engine.h    11 Mar 2011 08:28:04 -0000
@@ -101,6 +101,7 @@ void tb_start(void);
 void tb_end(void);
 
 int tbprintf(char *format, ...) GCC_PRINTFLIKE(1,2);
+int tbprintft(char *format, ...) GCC_PRINTFLIKE(1,2);
 
 void end_line(void);
 void end_page(void);
@@ -155,6 +156,7 @@ extern int columns, lines;
 
 extern int need_update;
 extern int need_sort;
+extern int separate_thousands;
 
 extern volatile sig_atomic_t gotsig_close;
 extern volatile sig_atomic_t gotsig_resize;
Index: if.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/if.c,v
retrieving revision 1.19
diff -p -u -p -u -r1.19 if.c
--- if.c        2 Mar 2011 06:48:17 -0000       1.19
+++ if.c        15 Mar 2011 08:22:11 -0000
@@ -44,6 +44,7 @@ struct ifstat {
 
 static int nifs = 0;
 static int num_ifs = 0;
+static int show_bits = 0;
 
 void print_if(void);
 int read_if(void);
@@ -288,6 +289,9 @@ fetchifstat(void)
 static void
 showifstat(struct ifstat *ifs)
 {
+       int conv = show_bits ? 8 : 1;
+       int div = show_bits ? 1000 : 1024;
+
        print_fld_str(FLD_IF_IFACE, ifs->ifs_name);
 
        tb_start();
@@ -309,11 +313,11 @@ showifstat(struct ifstat *ifs)
 
        print_fld_str(FLD_IF_DESC, ifs->ifs_description);
 
-       print_fld_size(FLD_IF_IBYTES, ifs->ifs_cur.ifc_ib);
+       print_fld_sdiv(FLD_IF_IBYTES, ifs->ifs_cur.ifc_ib * conv, div);
        print_fld_size(FLD_IF_IPKTS, ifs->ifs_cur.ifc_ip);
        print_fld_size(FLD_IF_IERRS, ifs->ifs_cur.ifc_ie);
 
-       print_fld_size(FLD_IF_OBYTES, ifs->ifs_cur.ifc_ob);
+       print_fld_sdiv(FLD_IF_OBYTES, ifs->ifs_cur.ifc_ob * conv, div);
        print_fld_size(FLD_IF_OPKTS, ifs->ifs_cur.ifc_op);
        print_fld_size(FLD_IF_OERRS, ifs->ifs_cur.ifc_oe);
 
@@ -325,13 +329,16 @@ showifstat(struct ifstat *ifs)
 static void
 showtotal(void)
 {
+       int conv = show_bits ? 8 : 1;
+       int div = show_bits ? 1000 : 1024;
+
        print_fld_str(FLD_IF_IFACE, "Totals");
 
-       print_fld_size(FLD_IF_IBYTES, sum.ifc_ib);
+       print_fld_sdiv(FLD_IF_IBYTES, sum.ifc_ib * conv, div);
        print_fld_size(FLD_IF_IPKTS, sum.ifc_ip);
        print_fld_size(FLD_IF_IERRS, sum.ifc_ie);
 
-       print_fld_size(FLD_IF_OBYTES, sum.ifc_ob);
+       print_fld_sdiv(FLD_IF_OBYTES, sum.ifc_ob * conv, div);
        print_fld_size(FLD_IF_OPKTS, sum.ifc_op);
        print_fld_size(FLD_IF_OERRS, sum.ifc_oe);
 
@@ -358,6 +365,17 @@ if_keyboard_callback(int ch)
                state = BOOT;
                for (ifs = ifstats; ifs < ifstats + nifs; ifs++)
                        bzero(&ifs->ifs_old, sizeof(ifs->ifs_old));
+               gotsig_alarm = 1;
+               break;
+       case 'B':
+               show_bits = !show_bits;
+               if (show_bits) {
+                       FLD_IF_IBYTES->title = "IBITS";
+                       FLD_IF_OBYTES->title = "OBITS";
+               } else {
+                       FLD_IF_IBYTES->title = "IBYTES";
+                       FLD_IF_OBYTES->title = "OBYTES";
+               }
                gotsig_alarm = 1;
                break;
        case 't':
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/main.c,v
retrieving revision 1.57
diff -p -u -p -u -r1.57 main.c
--- main.c      16 Jul 2010 05:22:48 -0000      1.57
+++ main.c      15 Mar 2011 08:27:18 -0000
@@ -315,6 +315,10 @@ keyboard_callback(int ch)
        case 's':
                command_set(&cm_delay, NULL);
                break;
+       case ',':
+               separate_thousands = !separate_thousands;
+               gotsig_alarm = 1;
+               break;
        case ':':
                command_set(&cm_compat, NULL);
                break;
Index: systat.1
===================================================================
RCS file: /cvs/src/usr.bin/systat/systat.1,v
retrieving revision 1.90
diff -p -u -p -u -r1.90 systat.1
--- systat.1    18 Jan 2011 03:38:05 -0000      1.90
+++ systat.1    15 Mar 2011 08:18:46 -0000
@@ -175,6 +175,8 @@ Quit
 .Nm .
 .It Ic r
 Reverse the selected ordering if supported by the view.
+.It Ic \,
+Print numbers with thousand separators, where applicable.
 .It Ic ^A \*(Ba Aq Ic Home
 Jump to the beginning of the current view.
 .It Ic ^B \*(Ba Aq Ic right arrow
@@ -257,6 +259,9 @@ represent whether the interface is conne
 in the case of
 .Xr carp 4
 interfaces, whether the interface is in master or backup state, respectively.
+The character
+.Ic B
+changes the counter view between bytes and bits.
 .\"See below for more options.
 .It Ic iostat
 Display statistics about disk throughput.

Reply via email to