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_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);
}

View File

@ -44,6 +44,7 @@ static const char copyright[] =
#include <sys/param.h>
#include <sys/time.h>
#include <sys/sysctl.h>
#include <sys/queue.h>
#include <err.h>
#include <limits.h>
@ -53,6 +54,7 @@ static const char copyright[] =
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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();

View File

@ -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