- Add new 'a' switch and runtime option that allows 'top' to display process

titles extracted from argv vector instead of the real executable names.
  This is useful when you want to watch applications that set their status
  information via setproctitle(3).

Approved by:	alfred
MFC after:	2 weeks
This commit is contained in:
Stanislav Sedov 2007-04-14 10:16:52 +00:00
parent c105859eee
commit faac60c8fc
4 changed files with 98 additions and 9 deletions

View file

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

View file

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

View file

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

View file

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