aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/top/top.X8
-rw-r--r--contrib/top/top.c21
-rw-r--r--contrib/top/top.h5
-rw-r--r--usr.bin/top/machine.c73
4 files changed, 98 insertions, 9 deletions
diff --git a/contrib/top/top.X b/contrib/top/top.X
index ff1a1d9aca86..304ee91e2b6f 100644
--- a/contrib/top/top.X
+++ b/contrib/top/top.X
@@ -10,7 +10,7 @@ top \- display and update information about the top cpu processes
.SH SYNOPSIS
.B top
[
-.B \-bCHIinqStuv
+.B \-abCHIinqStuv
] [
.BI \-d count
] [
@@ -78,6 +78,12 @@ the \*(lqWCPU\*(rq column respectively.
Show system processes in the display. Normally, system processes such as
the pager and the swapper are not shown. This option makes them visible.
.TP
+.B \-a
+Display command names derived from the argv[] vector, rather than real
+executable name. It's useful when you want to watch applications, that
+puts their status information there. If the real name differs from argv[0],
+it will be displayed in parenthesis.
+.TP
.B \-b
Use \*(lqbatch\*(rq mode. In this mode, all input from the terminal is
ignored. Interrupt characters (such as ^C and ^\e) still have an effect.
diff --git a/contrib/top/top.c b/contrib/top/top.c
index 81933e4454c6..970d143649da 100644
--- a/contrib/top/top.c
+++ b/contrib/top/top.c
@@ -65,6 +65,8 @@ extern char *optarg;
/* imported from screen.c */
extern int overstrike;
+static int fmt_flags = 0;
+
/* signal handling routines */
sigret_t leave();
sigret_t onalrm();
@@ -193,9 +195,9 @@ char *argv[];
fd_set readfds;
#ifdef ORDER
- static char command_chars[] = "\f qh?en#sdkriIutHmSCo";
+ static char command_chars[] = "\f qh?en#sdkriIutHmSCao";
#else
- static char command_chars[] = "\f qh?en#sdkriIutHmSC";
+ static char command_chars[] = "\f qh?en#sdkriIutHmSCa";
#endif
/* these defines enumerate the "strchr"s of the commands in command_chars */
#define CMD_redraw 0
@@ -219,8 +221,9 @@ char *argv[];
#define CMD_viewtog 17
#define CMD_viewsys 18
#define CMD_wcputog 19
+#define CMD_showargs 20
#ifdef ORDER
-#define CMD_order 20
+#define CMD_order 21
#endif
/* set the buffer for stdout */
@@ -277,7 +280,7 @@ char *argv[];
optind = 1;
}
- while ((i = getopt(ac, av, "CSIHbinquvs:d:U:m:o:t")) != EOF)
+ while ((i = getopt(ac, av, "CSIHabinquvs:d:U:m:o:t")) != EOF)
{
switch(i)
{
@@ -316,6 +319,10 @@ char *argv[];
interactive = No;
break;
+ case 'a':
+ fmt_flags ^= FMT_SHOWARGS;
+ break;
+
case 'd': /* number of displays to show */
if ((i = atoiwi(optarg)) == Invalid || i == 0)
{
@@ -651,7 +658,8 @@ restart:
/* now show the top "n" processes. */
for (i = 0; i < active_procs; i++)
{
- (*d_process)(i, format_next_process(processes, get_userid));
+ (*d_process)(i, format_next_process(processes, get_userid,
+ fmt_flags));
}
}
else
@@ -1020,6 +1028,9 @@ restart:
case CMD_viewsys:
ps.system = !ps.system;
break;
+ case CMD_showargs:
+ fmt_flags ^= FMT_SHOWARGS;
+ break;
#ifdef ORDER
case CMD_order:
new_message(MT_standout,
diff --git a/contrib/top/top.h b/contrib/top/top.h
index 59cdeed2d7d7..2b32d1007fd3 100644
--- a/contrib/top/top.h
+++ b/contrib/top/top.h
@@ -39,4 +39,9 @@ char *version_string();
enum displaymodes { DISP_CPU = 0, DISP_IO, DISP_MAX };
+/*
+ * Format modifiers
+ */
+#define FMT_SHOWARGS 0x00000001
+
extern enum displaymodes displaymode;
diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c
index d3f9ef08375c..7d973b8fabe8 100644
--- a/usr.bin/top/machine.c
+++ b/usr.bin/top/machine.c
@@ -45,6 +45,7 @@
#include <string.h>
#include <strings.h>
#include <unistd.h>
+#include <vis.h>
#include "top.h"
#include "machine.h"
@@ -649,7 +650,7 @@ get_process_info(struct system_info *si, struct process_select *sel,
static char fmt[128]; /* static area where result is built */
char *
-format_next_process(caddr_t handle, char *(*get_userid)(int))
+format_next_process(caddr_t handle, char *(*get_userid)(int), int flags)
{
struct kinfo_proc *pp;
const struct kinfo_proc *oldp;
@@ -661,6 +662,8 @@ format_next_process(caddr_t handle, char *(*get_userid)(int))
struct rusage ru, *rup;
long p_tot, s_tot;
char *proc_fmt, thr_buf[6];
+ char *cmdbuf = NULL;
+ char **args;
/* find and remember the next proc structure */
hp = (struct handle *)handle;
@@ -723,6 +726,65 @@ format_next_process(caddr_t handle, char *(*get_userid)(int))
break;
}
+ cmdbuf = (char *)malloc(cmdlengthdelta + 1);
+ if (cmdbuf == NULL) {
+ warn("malloc(%d)", cmdlengthdelta + 1);
+ return NULL;
+ }
+
+ if (!(flags & FMT_SHOWARGS)) {
+ snprintf(cmdbuf, cmdlengthdelta, "%s", pp->ki_comm);
+ }
+ else if (pp->ki_args == NULL ||
+ (args = kvm_getargv(kd, pp, cmdlengthdelta)) == NULL || !(*args))
+ snprintf(cmdbuf, cmdlengthdelta, "[%s]", pp->ki_comm);
+ else {
+ char *src, *dst, *argbuf;
+ char *cmd;
+ size_t argbuflen;
+ size_t len;
+
+ argbuflen = cmdlengthdelta * 4;
+ argbuf = (char *)malloc(argbuflen + 1);
+ if (argbuf == NULL) {
+ warn("malloc(%d)", argbuflen + 1);
+ free(cmdbuf);
+ return NULL;
+ }
+
+ dst = argbuf;
+
+ /* Extract cmd name from argv */
+ cmd = strrchr(*args, '/');
+ if (cmd == NULL)
+ cmd = *args;
+ else
+ cmd++;
+
+ for (; (src = *args++) != NULL; ) {
+ if (*src == '\0')
+ continue;
+ len = (argbuflen - (dst - argbuf) - 1) / 4;
+ strvisx(dst, src, strlen(src) < len ? strlen(src) : len,
+ VIS_NL | VIS_CSTYLE);
+ while (*dst != '\0')
+ dst++;
+ if ((argbuflen - (dst - argbuf) - 1) / 4 > 0)
+ *dst++ = ' '; /* add delimiting space */
+ }
+ if (dst != argbuf && dst[-1] == ' ')
+ dst--;
+ *dst = '\0';
+
+ if (strcmp(cmd, pp->ki_comm) != 0 )
+ snprintf(cmdbuf, cmdlengthdelta, "%s (%s)",argbuf, \
+ pp->ki_comm);
+ else
+ strlcpy(cmdbuf, argbuf, cmdlengthdelta);
+
+ free(argbuf);
+ }
+
if (displaymode == DISP_IO) {
oldp = get_old_proc(pp);
if (oldp != NULL) {
@@ -752,7 +814,10 @@ format_next_process(caddr_t handle, char *(*get_userid)(int))
s_tot == 0 ? 0.0 : (p_tot * 100.0 / s_tot),
screen_width > cmdlengthdelta ?
screen_width - cmdlengthdelta : 0,
- printable(pp->ki_comm));
+ printable(cmdbuf));
+
+ free(cmdbuf);
+
return (fmt);
}
@@ -777,7 +842,9 @@ format_next_process(caddr_t handle, char *(*get_userid)(int))
format_time(cputime),
ps.wcpu ? 100.0 * weighted_cpu(pct, pp) : 100.0 * pct,
screen_width > cmdlengthdelta ? screen_width - cmdlengthdelta : 0,
- printable(pp->ki_comm));
+ printable(cmdbuf));
+
+ free(cmdbuf);
/* return the result */
return (fmt);