Allow systat(1) interactive dispay-specific commands to

be specified via command line.

Submitted by:	vsevolod
MFC after:	2 weeks
This commit is contained in:
Alexander V. Chernikov 2014-05-09 16:20:55 +00:00
parent 827ac19dc2
commit 6052df8ef8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=265782
3 changed files with 103 additions and 18 deletions

View File

@ -77,7 +77,7 @@ struct if_stat {
u_long if_in_pps_peak; u_long if_in_pps_peak;
u_long if_out_pps_peak; u_long if_out_pps_peak;
u_int if_row; /* Index into ifmib sysctl */ 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 display;
u_int match; u_int match;
}; };
@ -210,13 +210,19 @@ showifstat(void)
struct if_stat *ifp = NULL; struct if_stat *ifp = NULL;
SLIST_FOREACH(ifp, &curlist, link) { SLIST_FOREACH(ifp, &curlist, link) {
if (ifp->display == 0 || (ifp->match == 0) || if (ifp->if_ypos < LINES - 3 && ifp->if_ypos != -1)
ifp->if_ypos > LINES - 3 - 1) if (ifp->display == 0 || ifp->match == 0) {
continue; wmove(wnd, ifp->if_ypos, 0);
PUTNAME(ifp); wclrtoeol(wnd);
PUTRATE(col2, ifp->if_ypos); wmove(wnd, ifp->if_ypos + 1, 0);
PUTRATE(col3, ifp->if_ypos); wclrtoeol(wnd);
PUTTOTAL(col4, ifp->if_ypos); }
else {
PUTNAME(ifp);
PUTRATE(col2, ifp->if_ypos);
PUTRATE(col3, ifp->if_ypos);
PUTTOTAL(col4, ifp->if_ypos);
}
} }
return; return;
@ -425,6 +431,8 @@ sort_interface_list(void)
ifp->if_ypos = y; ifp->if_ypos = y;
y += ROW_SPACING; y += ROW_SPACING;
} }
else
ifp->if_ypos = -1;
} }
needsort = 0; needsort = 0;
@ -476,14 +484,13 @@ cmdifstat(const char *cmd, const char *args)
retval = ifcmd(cmd, args); retval = ifcmd(cmd, args);
/* ifcmd() returns 1 on success */ /* ifcmd() returns 1 on success */
if (retval == 1) { if (retval == 1) {
showifstat();
refresh();
if (needclear) { if (needclear) {
showifstat();
refresh();
werase(wnd); werase(wnd);
labelifstat(); labelifstat();
needclear = 0; needclear = 0;
} }
} }
return (retval); return (retval);
} }

View File

@ -44,6 +44,7 @@ static const char copyright[] =
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/queue.h>
#include <err.h> #include <err.h>
#include <limits.h> #include <limits.h>
@ -53,6 +54,7 @@ static const char copyright[] =
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include "systat.h" #include "systat.h"
@ -77,12 +79,67 @@ int use_kvm = 1;
static WINDOW *wload; /* one line window for load average */ 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 int
main(int argc, char **argv) main(int argc, char **argv)
{ {
char errbuf[_POSIX2_LINE_MAX], dummy; char errbuf[_POSIX2_LINE_MAX], dummy;
size_t size; size_t size;
double t; double t;
struct cmdentry *cmd = NULL;
#ifdef USE_WIDECHAR #ifdef USE_WIDECHAR
(void) setlocale(LC_ALL, ""); (void) setlocale(LC_ALL, "");
@ -90,8 +147,9 @@ main(int argc, char **argv)
(void) setlocale(LC_TIME, ""); (void) setlocale(LC_TIME, "");
#endif #endif
SLIST_INIT(&commands);
argc--, argv++; argc--, argv++;
while (argc > 0) { if (argc > 0) {
if (argv[0][0] == '-') { if (argv[0][0] == '-') {
struct cmdtab *p; struct cmdtab *p;
@ -101,12 +159,10 @@ main(int argc, char **argv)
if (p == (struct cmdtab *)0) if (p == (struct cmdtab *)0)
errx(1, "%s: unknown request", &argv[0][1]); errx(1, "%s: unknown request", &argv[0][1]);
curcmd = p; curcmd = p;
} else { argc--, argv++;
t = strtod(argv[0], NULL) * 1000000.0;
if (t > 0 && t < (double)UINT_MAX)
delay = (unsigned int)t;
} }
argc--, argv++; parse_cmd_args (argc, argv);
} }
kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
if (kd != NULL) { if (kd != NULL) {
@ -169,8 +225,12 @@ main(int argc, char **argv)
curcmd->c_flags |= CF_INIT; curcmd->c_flags |= CF_INIT;
labels(); 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(); display();
noecho(); noecho();
crmode(); crmode();

View File

@ -37,6 +37,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl display .Op Fl display
.Op Ar display-commands
.Op Ar refresh-interval .Op Ar refresh-interval
.Sh DESCRIPTION .Sh DESCRIPTION
The The
@ -108,6 +109,23 @@ The
.Ar refresh-value .Ar refresh-value
specifies the screen refresh time interval in seconds. specifies the screen refresh time interval in seconds.
Time interval can be fractional. 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 .El
.Pp .Pp
Certain characters cause immediate action by Certain characters cause immediate action by