diff --git a/usr.bin/systat/ifstat.c b/usr.bin/systat/ifstat.c index 16328906832a..4cfe01c4d616 100644 --- a/usr.bin/systat/ifstat.c +++ b/usr.bin/systat/ifstat.c @@ -77,7 +77,7 @@ struct if_stat { u_long if_in_pps_peak; u_long if_out_pps_peak; u_int if_row; /* Index into ifmib sysctl */ - u_int if_ypos; /* 0 if not being displayed */ + int if_ypos; /* -1 if not being displayed */ u_int display; u_int match; }; @@ -210,13 +210,19 @@ showifstat(void) struct if_stat *ifp = NULL; SLIST_FOREACH(ifp, &curlist, link) { - if (ifp->display == 0 || (ifp->match == 0) || - ifp->if_ypos > LINES - 3 - 1) - continue; - PUTNAME(ifp); - PUTRATE(col2, ifp->if_ypos); - PUTRATE(col3, ifp->if_ypos); - PUTTOTAL(col4, ifp->if_ypos); + if (ifp->if_ypos < LINES - 3 && ifp->if_ypos != -1) + if (ifp->display == 0 || ifp->match == 0) { + wmove(wnd, ifp->if_ypos, 0); + wclrtoeol(wnd); + wmove(wnd, ifp->if_ypos + 1, 0); + wclrtoeol(wnd); + } + else { + PUTNAME(ifp); + PUTRATE(col2, ifp->if_ypos); + PUTRATE(col3, ifp->if_ypos); + PUTTOTAL(col4, ifp->if_ypos); + } } return; @@ -425,6 +431,8 @@ sort_interface_list(void) ifp->if_ypos = y; y += ROW_SPACING; } + else + ifp->if_ypos = -1; } needsort = 0; @@ -476,14 +484,13 @@ cmdifstat(const char *cmd, const char *args) retval = ifcmd(cmd, args); /* ifcmd() returns 1 on success */ if (retval == 1) { - showifstat(); - refresh(); if (needclear) { + showifstat(); + refresh(); werase(wnd); labelifstat(); needclear = 0; } } - return (retval); } diff --git a/usr.bin/systat/main.c b/usr.bin/systat/main.c index 8417811e222e..e80dc6133808 100644 --- a/usr.bin/systat/main.c +++ b/usr.bin/systat/main.c @@ -44,6 +44,7 @@ static const char copyright[] = #include #include #include +#include #include #include @@ -53,6 +54,7 @@ static const char copyright[] = #include #include #include +#include #include #include "systat.h" @@ -77,12 +79,67 @@ int use_kvm = 1; static WINDOW *wload; /* one line window for load average */ +struct cmdentry { + SLIST_ENTRY(cmdentry) link; + char *cmd; /* Command name */ + char *argv; /* Arguments vector for a command */ +}; +SLIST_HEAD(, cmdentry) commands; + +static void +parse_cmd_args (int argc, char **argv) +{ + int in_command = 0; + struct cmdentry *cmd = NULL; + double t; + + while (argc) { + if (argv[0][0] == '-') { + if (in_command) + SLIST_INSERT_HEAD(&commands, cmd, link); + + if (memcmp(argv[0], "--", 3) == 0) { + in_command = 0; /*-- ends a command explicitly*/ + argc --, argv ++; + continue; + } + cmd = calloc(1, sizeof(struct cmdentry)); + if (cmd == NULL) + errx(1, "memory allocating failure"); + cmd->cmd = strdup(&argv[0][1]); + if (cmd->cmd == NULL) + errx(1, "memory allocating failure"); + in_command = 1; + } + else if (!in_command) { + t = strtod(argv[0], NULL) * 1000000.0; + if (t > 0 && t < (double)UINT_MAX) + delay = (unsigned int)t; + } + else if (cmd != NULL) { + cmd->argv = strdup(argv[0]); + if (cmd->argv == NULL) + errx(1, "memory allocating failure"); + in_command = 0; + SLIST_INSERT_HEAD(&commands, cmd, link); + } + else + errx(1, "invalid arguments list"); + + argc--, argv++; + } + if (in_command && cmd != NULL) + SLIST_INSERT_HEAD(&commands, cmd, link); + +} + int main(int argc, char **argv) { char errbuf[_POSIX2_LINE_MAX], dummy; size_t size; double t; + struct cmdentry *cmd = NULL; #ifdef USE_WIDECHAR (void) setlocale(LC_ALL, ""); @@ -90,8 +147,9 @@ main(int argc, char **argv) (void) setlocale(LC_TIME, ""); #endif + SLIST_INIT(&commands); argc--, argv++; - while (argc > 0) { + if (argc > 0) { if (argv[0][0] == '-') { struct cmdtab *p; @@ -101,12 +159,10 @@ main(int argc, char **argv) if (p == (struct cmdtab *)0) errx(1, "%s: unknown request", &argv[0][1]); curcmd = p; - } else { - t = strtod(argv[0], NULL) * 1000000.0; - if (t > 0 && t < (double)UINT_MAX) - delay = (unsigned int)t; + argc--, argv++; } - argc--, argv++; + parse_cmd_args (argc, argv); + } kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); if (kd != NULL) { @@ -169,8 +225,12 @@ main(int argc, char **argv) curcmd->c_flags |= CF_INIT; labels(); - dellave = 0.0; + if (curcmd->c_cmd != NULL) + SLIST_FOREACH (cmd, &commands, link) + if (!curcmd->c_cmd(cmd->cmd, cmd->argv)) + warnx("command is not understood"); + dellave = 0.0; display(); noecho(); crmode(); diff --git a/usr.bin/systat/systat.1 b/usr.bin/systat/systat.1 index 9c144e7e2325..5fc3257c59b5 100644 --- a/usr.bin/systat/systat.1 +++ b/usr.bin/systat/systat.1 @@ -37,6 +37,7 @@ .Sh SYNOPSIS .Nm .Op Fl display +.Op Ar display-commands .Op Ar refresh-interval .Sh DESCRIPTION The @@ -108,6 +109,23 @@ The .Ar refresh-value specifies the screen refresh time interval in seconds. Time interval can be fractional. +.It Ar display-commands +A list of commands specific for this display. These commands can also +be entered interactively and are described for each display separately +below. If the command of the display requires an argument or arguments, +it is possible to specify them as separate command line argument. To finish +display commands it is possible to use double dash at the end +of the list. For example: +.Pp +.Dl Nm Fl ifstat Fl match Ar bge0,em1 Fl pps +.Pp +This will display statistics of packets per second for network interfaces +named as bge0 and em1. +.Pp +.Dl Nm Fl iostat Fl numeric Fl - Ar 2.1 +.Pp +This will display all IO statistics in a numeric format and the information +will be refreshed each 2.1 seconds. .El .Pp Certain characters cause immediate action by