svn commit: r333898 - in head: contrib/top usr.bin/top

Eitan Adler eadler at FreeBSD.org
Sat May 19 22:40:25 UTC 2018


Author: eadler
Date: Sat May 19 22:40:23 2018
New Revision: 333898
URL: https://svnweb.freebsd.org/changeset/base/333898

Log:
  top(1): Migrate top to usr.bin
  
  We've been maintaining top(1) for a long time, and the upstream
  hasn't existed/been used in similarly as long. Make it clear that we own
  top(1)
  
  Tested with 'make universe'. Everything passed except MIPS which failed
  for unrelated reasons. Install also tested for amd64.
  
  Reviewed by:		sbruno
  No objections:		imp, mmacy
  Differential Revision:	https://reviews.freebsd.org/D15387

Added:
     - copied unchanged from r333897, head/contrib/top/boolean.h
     - copied unchanged from r333897, head/contrib/top/commands.c
  head/usr.bin/top/commands.h
     - copied unchanged from r333897, head/contrib/top/commands.h
     - copied unchanged from r333897, head/contrib/top/display.c
     - copied unchanged from r333897, head/contrib/top/display.h
     - copied unchanged from r333897, head/contrib/top/getopt.c
     - copied unchanged from r333897, head/contrib/top/layout.h
     - copied unchanged from r333897, head/contrib/top/loadavg.h
     - copied unchanged from r333897, head/contrib/top/machine.h
     - copied unchanged from r333897, head/contrib/top/os.h
     - copied unchanged from r333897, head/contrib/top/patchlevel.h
     - copied unchanged from r333897, head/contrib/top/prime.c
     - copied unchanged from r333897, head/contrib/top/screen.c
     - copied unchanged from r333897, head/contrib/top/screen.h
     - copied unchanged from r333897, head/contrib/top/sigconv.awk
  head/usr.bin/top/top.1   (contents, props changed)
     - copied unchanged from r333897, head/contrib/top/top.c
     - copied unchanged from r333897, head/contrib/top/top.h
     - copied unchanged from r333897, head/contrib/top/top.local.hs
     - copied unchanged from r333897, head/contrib/top/top.xs
     - copied unchanged from r333897, head/contrib/top/username.c
  head/usr.bin/top/username.h
     - copied unchanged from r333897, head/contrib/top/username.h
     - copied unchanged from r333897, head/contrib/top/utils.c
     - copied unchanged from r333897, head/contrib/top/utils.h
     - copied unchanged from r333897, head/contrib/top/version.c
Directory Properties:
  head/usr.bin/top/boolean.h   (props changed)
  head/usr.bin/top/commands.c   (props changed)
  head/usr.bin/top/display.c   (props changed)
  head/usr.bin/top/display.h   (props changed)
  head/usr.bin/top/getopt.c   (props changed)
  head/usr.bin/top/layout.h   (props changed)
  head/usr.bin/top/loadavg.h   (props changed)
  head/usr.bin/top/machine.h   (props changed)
  head/usr.bin/top/os.h   (props changed)
  head/usr.bin/top/patchlevel.h   (props changed)
  head/usr.bin/top/prime.c   (props changed)
  head/usr.bin/top/screen.c   (props changed)
  head/usr.bin/top/screen.h   (props changed)
  head/usr.bin/top/sigconv.awk   (props changed)
  head/usr.bin/top/top.c   (props changed)
  head/usr.bin/top/top.h   (props changed)
  head/usr.bin/top/top.local.hs   (props changed)
  head/usr.bin/top/top.xs   (props changed)
  head/usr.bin/top/username.c   (props changed)
  head/usr.bin/top/utils.c   (props changed)
  head/usr.bin/top/utils.h   (props changed)
  head/usr.bin/top/version.c   (props changed)
Deleted:
  head/contrib/top/
  head/usr.bin/top/top.local.1
Modified:
  head/usr.bin/top/Makefile   (contents, props changed)
Directory Properties:
  head/usr.bin/top/machine.c   (props changed)

Modified: head/usr.bin/top/Makefile
==============================================================================
--- head/usr.bin/top/Makefile	Sat May 19 22:04:54 2018	(r333897)
+++ head/usr.bin/top/Makefile	Sat May 19 22:40:23 2018	(r333898)
@@ -1,36 +1,21 @@
 # $FreeBSD$
 
-TOPDIR=	${SRCTOP}/contrib/top
-.PATH: ${TOPDIR}
-
 PROG=	top
 SRCS=	commands.c display.c machine.c screen.c top.c \
-	username.c utils.c version.c
+	username.c utils.c version.c 
 SRCS+=	sigdesc.h top.local.h
-CFLAGS+= -DHAVE_GETOPT -DHAVE_STRERROR -DORDER
-CFLAGS+= -I${.CURDIR} -I${TOPDIR} -I.
+CFLAGS+= -DHAVE_GETOPT -DHAVE_STRERROR -DORDER -I ${.OBJDIR}
+MAN=	top.1
 
 WARNS?=	0
 
-#
-# The table size should be a prime number approximately twice as
-# large as the number of lines in /etc/passwd.  The default number
-# is 20011; use /etc/make.conf to override this.
-#
-.if defined(TOP_TABLE_SIZE)
-CFLAGS+= -D"Table_size=${TOP_TABLE_SIZE}"
-.endif
-
 LIBADD=	ncursesw m kvm jail
 
 CLEANFILES= sigdesc.h
-SIGCONV_AWK= ${SRCTOP}/contrib/top/sigconv.awk
-STAGED_INCLUDE_DIR?= ${DESTDIR}/usr/include
-SIGNAL_H= ${STAGED_INCLUDE_DIR}/sys/signal.h
-sigdesc.h: ${SIGCONV_AWK} ${SIGNAL_H}
-	awk -f ${SIGCONV_AWK} < ${SIGNAL_H} > ${.TARGET}
+SIGNAL_H= ${SRCTOP}/sys/sys/signal.h
+sigdesc.h: sigconv.awk ${SIGNAL_H}
+	awk -f ${SRCTOP}/usr.bin/top/sigconv.awk < ${SIGNAL_H} > ${.TARGET}
 
-CLEANFILES+= top.local.h top.x
 .SUFFIXES: .xs .x .hs .h
 .xs.x .hs.h:
 	@${ECHO} Making ${.TARGET} from ${.IMPSRC}
@@ -41,9 +26,5 @@ CLEANFILES+= top.local.h top.x
 	-e's,%delay%,2,g' \
 	-e's,%random%,1,g' \
 	${.IMPSRC} > ${.TARGET}
-
-CLEANFILES+= top.1
-top.1: top.x top.local.1
-	cat ${.ALLSRC} > ${.TARGET}
 
 .include <bsd.prog.mk>

Copied: head/usr.bin/top/boolean.h (from r333897, head/contrib/top/boolean.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/top/boolean.h	Sat May 19 22:40:23 2018	(r333898, copy of r333897, head/contrib/top/boolean.h)
@@ -0,0 +1,5 @@
+/* My favorite names for boolean values */
+#define  No	0
+#define  Yes	1
+#define  Maybe	2		/* tri-state boolean, actually */
+

Copied: head/usr.bin/top/commands.c (from r333897, head/contrib/top/commands.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/top/commands.c	Sat May 19 22:40:23 2018	(r333898, copy of r333897, head/contrib/top/commands.c)
@@ -0,0 +1,542 @@
+/*
+ *  Top users/processes display for Unix
+ *  Version 3
+ *
+ *  This program may be freely redistributed,
+ *  but this entire comment MUST remain intact.
+ *
+ *  Copyright (c) 1984, 1989, William LeFebvre, Rice University
+ *  Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
+ *
+ * $FreeBSD$
+ */
+
+/*
+ *  This file contains the routines that implement some of the interactive
+ *  mode commands.  Note that some of the commands are implemented in-line
+ *  in "main".  This is necessary because they change the global state of
+ *  "top" (i.e.:  changing the number of processes to display).
+ */
+
+#include "os.h"
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include "commands.h"
+#include "sigdesc.h"		/* generated automatically */
+#include "top.h"
+#include "boolean.h"
+#include "utils.h"
+#include "machine.h"
+
+extern int  errno;
+
+extern char *copyright;
+
+/* imported from screen.c */
+extern int overstrike;
+
+int err_compar();
+char *err_string();
+static int str_adderr(char *str, int len, int err);
+static int str_addarg(char *str, int len, char *arg, int first);
+
+/*
+ *  show_help() - display the help screen; invoked in response to
+ *		either 'h' or '?'.
+ */
+
+void
+show_help()
+
+{
+    printf("Top version %s, %s\n", version_string(), copyright);
+    fputs("\n\n\
+A top users display for Unix\n\
+\n\
+These single-character commands are available:\n\
+\n\
+^L      - redraw screen\n\
+q       - quit\n\
+h or ?  - help; show this text\n", stdout);
+
+    /* not all commands are availalbe with overstrike terminals */
+    if (overstrike)
+    {
+	fputs("\n\
+Other commands are also available, but this terminal is not\n\
+sophisticated enough to handle those commands gracefully.\n\n", stdout);
+    }
+    else
+    {
+	fputs("\
+C       - toggle the displaying of weighted CPU percentage\n\
+d       - change number of displays to show\n\
+e       - list errors generated by last \"kill\" or \"renice\" command\n\
+H       - toggle the displaying of threads\n\
+i or I  - toggle the displaying of idle processes\n\
+j       - toggle the displaying of jail ID\n\
+J       - display processes for only one jail (+ selects all jails)\n\
+k       - kill processes; send a signal to a list of processes\n\
+m       - toggle the display between 'cpu' and 'io' modes\n\
+n or #  - change number of processes to display\n", stdout);
+#ifdef ORDER
+	if (displaymode == DISP_CPU)
+		fputs("\
+o       - specify sort order (pri, size, res, cpu, time, threads, jid, pid)\n",
+	    stdout);
+	else
+		fputs("\
+o       - specify sort order (vcsw, ivcsw, read, write, fault, total, jid, pid)\n",
+	    stdout);
+#endif
+	fputs("\
+P       - toggle the displaying of per-CPU statistics\n\
+r       - renice a process\n\
+s       - change number of seconds to delay between updates\n\
+S       - toggle the displaying of system processes\n\
+a       - toggle the displaying of process titles\n\
+t       - toggle the display of this process\n\
+u       - display processes for only one user (+ selects all users)\n\
+w       - toggle the display of swap use for each process\n\
+z       - toggle the displaying of the system idle process\n\
+\n\
+\n", stdout);
+    }
+}
+
+/*
+ *  Utility routines that help with some of the commands.
+ */
+
+char *next_field(str)
+
+register char *str;
+
+{
+    if ((str = strchr(str, ' ')) == NULL)
+    {
+	return(NULL);
+    }
+    *str = '\0';
+    while (*++str == ' ') /* loop */;
+
+    /* if there is nothing left of the string, return NULL */
+    /* This fix is dedicated to Greg Earle */
+    return(*str == '\0' ? NULL : str);
+}
+
+int
+scanint(str, intp)
+
+char *str;
+int  *intp;
+
+{
+    register int val = 0;
+    register char ch;
+
+    /* if there is nothing left of the string, flag it as an error */
+    /* This fix is dedicated to Greg Earle */
+    if (*str == '\0')
+    {
+	return(-1);
+    }
+
+    while ((ch = *str++) != '\0')
+    {
+	if (isdigit(ch))
+	{
+	    val = val * 10 + (ch - '0');
+	}
+	else if (isspace(ch))
+	{
+	    break;
+	}
+	else
+	{
+	    return(-1);
+	}
+    }
+    *intp = val;
+    return(0);
+}
+
+/*
+ *  Some of the commands make system calls that could generate errors.
+ *  These errors are collected up in an array of structures for later
+ *  contemplation and display.  Such routines return a string containing an
+ *  error message, or NULL if no errors occurred.  The next few routines are
+ *  for manipulating and displaying these errors.  We need an upper limit on
+ *  the number of errors, so we arbitrarily choose 20.
+ */
+
+#define ERRMAX 20
+
+struct errs		/* structure for a system-call error */
+{
+    int  errnum;	/* value of errno (that is, the actual error) */
+    char *arg;		/* argument that caused the error */
+};
+
+static struct errs errs[ERRMAX];
+static int errcnt;
+static char *err_toomany = " too many errors occurred";
+static char *err_listem = 
+	" Many errors occurred.  Press `e' to display the list of errors.";
+
+/* These macros get used to reset and log the errors */
+#define ERR_RESET   errcnt = 0
+#define ERROR(p, e) if (errcnt >= ERRMAX) \
+		    { \
+			return(err_toomany); \
+		    } \
+		    else \
+		    { \
+			errs[errcnt].arg = (p); \
+			errs[errcnt++].errnum = (e); \
+		    }
+
+/*
+ *  err_string() - return an appropriate error string.  This is what the
+ *	command will return for displaying.  If no errors were logged, then
+ *	return NULL.  The maximum length of the error string is defined by
+ *	"STRMAX".
+ */
+
+#define STRMAX 80
+
+char *err_string()
+
+{
+    register struct errs *errp;
+    register int  cnt = 0;
+    register int  first = Yes;
+    register int  currerr = -1;
+    int stringlen;		/* characters still available in "string" */
+    static char string[STRMAX];
+
+    /* if there are no errors, return NULL */
+    if (errcnt == 0)
+    {
+	return(NULL);
+    }
+
+    /* sort the errors */
+    qsort((char *)errs, errcnt, sizeof(struct errs), err_compar);
+
+    /* need a space at the front of the error string */
+    string[0] = ' ';
+    string[1] = '\0';
+    stringlen = STRMAX - 2;
+
+    /* loop thru the sorted list, building an error string */
+    while (cnt < errcnt)
+    {
+	errp = &(errs[cnt++]);
+	if (errp->errnum != currerr)
+	{
+	    if (currerr != -1)
+	    {
+		if ((stringlen = str_adderr(string, stringlen, currerr)) < 2)
+		{
+		    return(err_listem);
+		}
+		(void) strcat(string, "; ");	  /* we know there's more */
+	    }
+	    currerr = errp->errnum;
+	    first = Yes;
+	}
+	if ((stringlen = str_addarg(string, stringlen, errp->arg, first)) ==0)
+	{
+	    return(err_listem);
+	}
+	first = No;
+    }
+
+    /* add final message */
+    stringlen = str_adderr(string, stringlen, currerr);
+
+    /* return the error string */
+    return(stringlen == 0 ? err_listem : string);
+}
+
+/*
+ *  str_adderr(str, len, err) - add an explanation of error "err" to
+ *	the string "str".
+ */
+
+static int
+str_adderr(str, len, err)
+
+char *str;
+int len;
+int err;
+
+{
+    register char *msg;
+    register int  msglen;
+
+    msg = err == 0 ? "Not a number" : errmsg(err);
+    msglen = strlen(msg) + 2;
+    if (len <= msglen)
+    {
+	return(0);
+    }
+    (void) strcat(str, ": ");
+    (void) strcat(str, msg);
+    return(len - msglen);
+}
+
+/*
+ *  str_addarg(str, len, arg, first) - add the string argument "arg" to
+ *	the string "str".  This is the first in the group when "first"
+ *	is set (indicating that a comma should NOT be added to the front).
+ */
+
+static int
+str_addarg(str, len, arg, first)
+
+char *str;
+int  len;
+char *arg;
+int  first;
+
+{
+    register int arglen;
+
+    arglen = strlen(arg);
+    if (!first)
+    {
+	arglen += 2;
+    }
+    if (len <= arglen)
+    {
+	return(0);
+    }
+    if (!first)
+    {
+	(void) strcat(str, ", ");
+    }
+    (void) strcat(str, arg);
+    return(len - arglen);
+}
+
+/*
+ *  err_compar(p1, p2) - comparison routine used by "qsort"
+ *	for sorting errors.
+ */
+
+int
+err_compar(p1, p2)
+
+register struct errs *p1, *p2;
+
+{
+    register int result;
+
+    if ((result = p1->errnum - p2->errnum) == 0)
+    {
+	return(strcmp(p1->arg, p2->arg));
+    }
+    return(result);
+}
+
+/*
+ *  error_count() - return the number of errors currently logged.
+ */
+
+int
+error_count()
+
+{
+    return(errcnt);
+}
+
+/*
+ *  show_errors() - display on stdout the current log of errors.
+ */
+
+void
+show_errors()
+
+{
+    register int cnt = 0;
+    register struct errs *errp = errs;
+
+    printf("%d error%s:\n\n", errcnt, errcnt == 1 ? "" : "s");
+    while (cnt++ < errcnt)
+    {
+	printf("%5s: %s\n", errp->arg,
+	    errp->errnum == 0 ? "Not a number" : errmsg(errp->errnum));
+	errp++;
+    }
+}
+
+/*
+ *  kill_procs(str) - send signals to processes, much like the "kill"
+ *		command does; invoked in response to 'k'.
+ */
+
+char *kill_procs(str)
+
+char *str;
+
+{
+    register char *nptr;
+    int signum = SIGTERM;	/* default */
+    int procnum;
+    struct sigdesc *sigp;
+    int uid;
+
+    /* reset error array */
+    ERR_RESET;
+
+    /* remember our uid */
+    uid = getuid();
+
+    /* skip over leading white space */
+    while (isspace(*str)) str++;
+
+    if (str[0] == '-')
+    {
+	/* explicit signal specified */
+	if ((nptr = next_field(str)) == NULL)
+	{
+	    return(" kill: no processes specified");
+	}
+
+	if (isdigit(str[1]))
+	{
+	    (void) scanint(str + 1, &signum);
+	    if (signum <= 0 || signum >= NSIG)
+	    {
+		return(" invalid signal number");
+	    }
+	}
+	else 
+	{
+	    /* translate the name into a number */
+	    for (sigp = sigdesc; sigp->name != NULL; sigp++)
+	    {
+		if (strcmp(sigp->name, str + 1) == 0)
+		{
+		    signum = sigp->number;
+		    break;
+		}
+	    }
+
+	    /* was it ever found */
+	    if (sigp->name == NULL)
+	    {
+		return(" bad signal name");
+	    }
+	}
+	/* put the new pointer in place */
+	str = nptr;
+    }
+
+    /* loop thru the string, killing processes */
+    do
+    {
+	if (scanint(str, &procnum) == -1)
+	{
+	    ERROR(str, 0);
+	}
+	else
+	{
+	    /* check process owner if we're not root */
+	    if (uid && (uid != proc_owner(procnum)))
+	    {
+		ERROR(str, EACCES);
+	    }
+	    /* go in for the kill */
+	    else if (kill(procnum, signum) == -1)
+	    {
+		/* chalk up an error */
+		ERROR(str, errno);
+	    }
+	}
+    } while ((str = next_field(str)) != NULL);
+
+    /* return appropriate error string */
+    return(err_string());
+}
+
+/*
+ *  renice_procs(str) - change the "nice" of processes, much like the
+ *		"renice" command does; invoked in response to 'r'.
+ */
+
+char *renice_procs(str)
+
+char *str;
+
+{
+    register char negate;
+    int prio;
+    int procnum;
+    int uid;
+
+    ERR_RESET;
+    uid = getuid();
+
+    /* allow for negative priority values */
+    if ((negate = (*str == '-')) != 0)
+    {
+	/* move past the minus sign */
+	str++;
+    }
+
+    /* use procnum as a temporary holding place and get the number */
+    procnum = scanint(str, &prio);
+
+    /* negate if necessary */
+    if (negate)
+    {
+	prio = -prio;
+    }
+
+#if defined(PRIO_MIN) && defined(PRIO_MAX)
+    /* check for validity */
+    if (procnum == -1 || prio < PRIO_MIN || prio > PRIO_MAX)
+    {
+	return(" bad priority value");
+    }
+#endif
+
+    /* move to the first process number */
+    if ((str = next_field(str)) == NULL)
+    {
+	return(" no processes specified");
+    }
+
+    /* loop thru the process numbers, renicing each one */
+    do
+    {
+	if (scanint(str, &procnum) == -1)
+	{
+	    ERROR(str, 0);
+	}
+
+	/* check process owner if we're not root */
+	else if (uid && (uid != proc_owner(procnum)))
+	{
+	    ERROR(str, EACCES);
+	}
+	else if (setpriority(PRIO_PROCESS, procnum, prio) == -1)
+	{
+	    ERROR(str, errno);
+	}
+    } while ((str = next_field(str)) != NULL);
+
+    /* return appropriate error string */
+    return(err_string());
+}
+

Copied: head/usr.bin/top/commands.h (from r333897, head/contrib/top/commands.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/top/commands.h	Sat May 19 22:40:23 2018	(r333898, copy of r333897, head/contrib/top/commands.h)
@@ -0,0 +1,21 @@
+/*
+ *  Top users/processes display for Unix
+ *  Version 3
+ *
+ *  This program may be freely redistributed,
+ *  but this entire comment MUST remain intact.
+ *
+ *  Copyright (c) 1984, 1989, William LeFebvre, Rice University
+ *  Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
+ *  Copyright (c) 2016, Randy Westlund
+ *
+ * $FreeBSD$
+ */
+#ifndef COMMANDS_H
+#define COMMANDS_H
+
+void	show_errors(void);
+int	error_count(void);
+void	show_help(void);
+
+#endif /* COMMANDS_H */

Copied: head/usr.bin/top/display.c (from r333897, head/contrib/top/display.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/top/display.c	Sat May 19 22:40:23 2018	(r333898, copy of r333897, head/contrib/top/display.c)
@@ -0,0 +1,1455 @@
+/*
+ *  Top users/processes display for Unix
+ *  Version 3
+ *
+ *  This program may be freely redistributed,
+ *  but this entire comment MUST remain intact.
+ *
+ *  Copyright (c) 1984, 1989, William LeFebvre, Rice University
+ *  Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
+ *
+ * $FreeBSD$
+ */
+
+/*
+ *  This file contains the routines that display information on the screen.
+ *  Each section of the screen has two routines:  one for initially writing
+ *  all constant and dynamic text, and one for only updating the text that
+ *  changes.  The prefix "i_" is used on all the "initial" routines and the
+ *  prefix "u_" is used for all the "updating" routines.
+ *
+ *  ASSUMPTIONS:
+ *        None of the "i_" routines use any of the termcap capabilities.
+ *        In this way, those routines can be safely used on terminals that
+ *        have minimal (or nonexistant) terminal capabilities.
+ *
+ *        The routines are called in this order:  *_loadave, i_timeofday,
+ *        *_procstates, *_cpustates, *_memory, *_message, *_header,
+ *        *_process, u_endscreen.
+ */
+
+#include "os.h"
+
+#include <sys/time.h>
+
+#include <curses.h>
+#include <ctype.h>
+#include <termcap.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "screen.h"		/* interface to screen package */
+#include "layout.h"		/* defines for screen position layout */
+#include "display.h"
+#include "top.h"
+#include "top.local.h"
+#include "boolean.h"
+#include "machine.h"		/* we should eliminate this!!! */
+#include "utils.h"
+
+#ifdef DEBUG
+FILE *debug;
+#endif
+
+/* imported from screen.c */
+extern int overstrike;
+
+static int lmpid = 0;
+static int last_hi = 0;		/* used in u_process and u_endscreen */
+static int lastline = 0;
+static int display_width = MAX_COLS;
+
+#define lineindex(l) ((l)*display_width)
+
+
+/* things initialized by display_init and used thruout */
+
+/* buffer of proc information lines for display updating */
+char *screenbuf = NULL;
+
+static char **procstate_names;
+static char **cpustate_names;
+static char **memory_names;
+static char **arc_names;
+static char **carc_names;
+static char **swap_names;
+
+static int num_procstates;
+static int num_cpustates;
+static int num_memory;
+static int num_swap;
+
+static int *lprocstates;
+static int *lcpustates;
+static int *lmemory;
+static int *lswap;
+
+static int num_cpus;
+static int *cpustate_columns;
+static int cpustate_total_length;
+static int cpustates_column;
+
+static enum { OFF, ON, ERASE } header_status = ON;
+
+static int string_count();
+static void summary_format();
+static void line_update();
+
+int  x_lastpid =	10;
+int  y_lastpid =	0;
+int  x_loadave =	33;
+int  x_loadave_nompid =	15;
+int  y_loadave =	0;
+int  x_procstate =	0;
+int  y_procstate =	1;
+int  x_brkdn =		15;
+int  y_brkdn =		1;
+int  x_mem =		5;
+int  y_mem =		3;
+int  x_arc =		5;
+int  y_arc =		4;
+int  x_carc =		5;
+int  y_carc =		5;
+int  x_swap =		6;
+int  y_swap =		4;
+int  y_message =	5;
+int  x_header =		0;
+int  y_header =		6;
+int  x_idlecursor =	0;
+int  y_idlecursor =	5;
+int  y_procs =		7;
+
+int  y_cpustates =	2;
+int  Header_lines =	7;
+
+int display_resize()
+
+{
+    register int lines;
+
+    /* first, deallocate any previous buffer that may have been there */
+    if (screenbuf != NULL)
+    {
+	free(screenbuf);
+    }
+
+    /* calculate the current dimensions */
+    /* if operating in "dumb" mode, we only need one line */
+    lines = smart_terminal ? screen_length - Header_lines : 1;
+
+    if (lines < 0)
+	lines = 0;
+    /* we don't want more than MAX_COLS columns, since the machine-dependent
+       modules make static allocations based on MAX_COLS and we don't want
+       to run off the end of their buffers */
+    display_width = screen_width;
+    if (display_width >= MAX_COLS)
+    {
+	display_width = MAX_COLS - 1;
+    }
+
+    /* now, allocate space for the screen buffer */
+    screenbuf = (char *)malloc(lines * display_width);
+    if (screenbuf == (char *)NULL)
+    {
+	/* oops! */
+	return(-1);
+    }
+
+    /* return number of lines available */
+    /* for dumb terminals, pretend like we can show any amount */
+    return(smart_terminal ? lines : Largest);
+}
+
+int display_updatecpus(statics)
+
+struct statics *statics;
+
+{
+    register int *lp;
+    register int lines;
+    register int i;
+    
+    /* call resize to do the dirty work */
+    lines = display_resize();
+    if (pcpu_stats)
+	num_cpus = statics->ncpus;
+    else
+	num_cpus = 1;
+    cpustates_column = 5;	/* CPU: */
+    if (num_cpus != 1)
+    cpustates_column += 2;	/* CPU 0: */
+    for (i = num_cpus; i > 9; i /= 10)
+	cpustates_column++;
+
+    /* fill the "last" array with all -1s, to insure correct updating */
+    lp = lcpustates;
+    i = num_cpustates * num_cpus;
+    while (--i >= 0)
+    {
+	*lp++ = -1;
+    }
+    
+    return(lines);
+}
+    
+int display_init(statics)
+
+struct statics *statics;
+
+{
+    register int lines;
+    register char **pp;
+    register int *ip;
+    register int i;
+
+    lines = display_updatecpus(statics);
+
+    /* only do the rest if we need to */
+    if (lines > -1)
+    {
+	/* save pointers and allocate space for names */
+	procstate_names = statics->procstate_names;
+	num_procstates = string_count(procstate_names);
+	lprocstates = (int *)malloc(num_procstates * sizeof(int));
+
+	cpustate_names = statics->cpustate_names;
+
+	swap_names = statics->swap_names;
+	num_swap = string_count(swap_names);
+	lswap = (int *)malloc(num_swap * sizeof(int));
+	num_cpustates = string_count(cpustate_names);
+	lcpustates = (int *)malloc(num_cpustates * sizeof(int) * statics->ncpus);
+	cpustate_columns = (int *)malloc(num_cpustates * sizeof(int));
+
+	memory_names = statics->memory_names;
+	num_memory = string_count(memory_names);
+	lmemory = (int *)malloc(num_memory * sizeof(int));
+
+	arc_names = statics->arc_names;
+	carc_names = statics->carc_names;
+	
+	/* calculate starting columns where needed */
+	cpustate_total_length = 0;
+	pp = cpustate_names;
+	ip = cpustate_columns;
+	while (*pp != NULL)
+	{
+	    *ip++ = cpustate_total_length;
+	    if ((i = strlen(*pp++)) > 0)
+	    {
+		cpustate_total_length += i + 8;
+	    }
+	}
+    }
+
+    /* return number of lines available */
+    return(lines);
+}
+
+void
+i_loadave(mpid, avenrun)
+
+int mpid;
+double *avenrun;
+
+{
+    register int i;
+
+    /* i_loadave also clears the screen, since it is first */
+    top_clear();
+
+    /* mpid == -1 implies this system doesn't have an _mpid */
+    if (mpid != -1)
+    {
+	printf("last pid: %5d;  ", mpid);
+    }
+
+    printf("load averages");
+
+    for (i = 0; i < 3; i++)
+    {
+	printf("%c %5.2f",
+	    i == 0 ? ':' : ',',
+	    avenrun[i]);
+    }
+    lmpid = mpid;
+}
+
+void
+u_loadave(mpid, avenrun)
+
+int mpid;
+double *avenrun;
+
+{
+    register int i;
+
+    if (mpid != -1)
+    {
+	/* change screen only when value has really changed */
+	if (mpid != lmpid)
+	{
+	    Move_to(x_lastpid, y_lastpid);
+	    printf("%5d", mpid);
+	    lmpid = mpid;
+	}
+
+	/* i remembers x coordinate to move to */
+	i = x_loadave;
+    }
+    else
+    {
+	i = x_loadave_nompid;
+    }
+
+    /* move into position for load averages */
+    Move_to(i, y_loadave);
+
+    /* display new load averages */
+    /* we should optimize this and only display changes */
+    for (i = 0; i < 3; i++)
+    {
+	printf("%s%5.2f",
+	    i == 0 ? "" : ", ",
+	    avenrun[i]);
+    }
+}
+
+void
+i_timeofday(tod)
+
+time_t *tod;
+
+{
+    /*
+     *  Display the current time.
+     *  "ctime" always returns a string that looks like this:
+     *  
+     *	Sun Sep 16 01:03:52 1973
+     *      012345678901234567890123
+     *	          1         2
+     *
+     *  We want indices 11 thru 18 (length 8).
+     */
+
+    if (smart_terminal)
+    {
+	Move_to(screen_width - 8, 0);
+    }
+    else
+    {
+	fputs("    ", stdout);
+    }
+#ifdef DEBUG
+    {
+	char *foo;
+	foo = ctime(tod);
+	fputs(foo, stdout);
+    }
+#endif
+    printf("%-8.8s\n", &(ctime(tod)[11]));
+    lastline = 1;
+}
+
+static int ltotal = 0;
+static char procstates_buffer[MAX_COLS];
+
+/*
+ *  *_procstates(total, brkdn, names) - print the process summary line
+ *
+ *  Assumptions:  cursor is at the beginning of the line on entry
+ *		  lastline is valid
+ */
+
+void

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list