summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/top/Makefile4
-rw-r--r--usr.bin/top/commands.c72
-rw-r--r--usr.bin/top/display.c684
-rw-r--r--usr.bin/top/display.h53
-rw-r--r--usr.bin/top/machine.c5
-rw-r--r--usr.bin/top/machine.h4
-rw-r--r--usr.bin/top/screen.c120
-rw-r--r--usr.bin/top/screen.h12
-rw-r--r--usr.bin/top/top.17
-rw-r--r--usr.bin/top/top.c182
-rw-r--r--usr.bin/top/top.h13
11 files changed, 391 insertions, 765 deletions
diff --git a/usr.bin/top/Makefile b/usr.bin/top/Makefile
index 55464d1937a..65759057f27 100644
--- a/usr.bin/top/Makefile
+++ b/usr.bin/top/Makefile
@@ -1,10 +1,10 @@
-# $OpenBSD: Makefile,v 1.12 2007/02/23 13:31:45 millert Exp $
+# $OpenBSD: Makefile,v 1.13 2007/05/29 00:56:56 otto Exp $
#
# Makefile for OpenBSD top-3.4.
PROG= top
-CFLAGS+=-I.
+CFLAGS+=-I. -Wall -g -Wmissing-prototypes
SRCS= commands.c display.c machine.c screen.c top.c username.c utils.c \
version.c
DPADD= ${LIBCURSES}
diff --git a/usr.bin/top/commands.c b/usr.bin/top/commands.c
index c246d86e681..d2b85bcb87c 100644
--- a/usr.bin/top/commands.c
+++ b/usr.bin/top/commands.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: commands.c,v 1.27 2007/02/23 13:31:45 millert Exp $ */
+/* $OpenBSD: commands.c,v 1.28 2007/05/29 00:56:56 otto Exp $ */
/*
* Top users/processes display for Unix
@@ -60,46 +60,6 @@ static size_t str_addarg(char *, size_t, char *, int);
static int err_compar(const void *, const void *);
/*
- * show_help() - display the help screen; invoked in response to
- * either 'h' or '?'.
- */
-void
-show_help(void)
-{
- printf("Top version %s, %s\n", version_string(), copyright);
- puts("These single-character commands are available:\n"
- "\n"
- "h | ? - help; show this text\n"
- "^L - redraw screen\n"
- "q - quit");
-
- /* not all commands are available with overstrike terminals */
- if (overstrike) {
- puts("\n"
- "Other commands are also available, but this terminal is not\n"
- "sophisticated enough to handle those commands gracefully.\n");
- } else {
- puts(
- "+ - reset any g, p, or u filters\n"
- "C - toggle the display of command line arguments\n"
- "d count - show `count' displays, then exit\n"
- "e - list errors generated by last \"kill\" or \"renice\" command\n"
- "g string - filter on command name (g+ selects all commands)\n"
- "I | i - toggle the display of idle processes\n"
- "k [-sig] pid - send signal `-sig' to process `pid'\n"
- "n|# count - show `count' processes\n"
- "o field - specify sort order (size, res, cpu, time, pri)\n"
- "p pid - display process by `pid' (p+ selects all processes)\n"
- "r count pid - renice process `pid' to nice value `count'\n"
- "S - toggle the display of system processes\n"
- "s time - change delay between displays to `time' seconds\n"
- "T - toggle the display of threads\n"
- "u user - display processes for `user' (u+ selects all users)\n"
- "\n");
- }
-}
-
-/*
* Utility routines that help with some of the commands.
*/
static char *
@@ -151,13 +111,8 @@ scanint(char *str, int *intp)
#define ERRMAX 20
-struct errs { /* structure for a system-call error */
- int err; /* value of errno (that is, the actual error) */
- char *arg; /* argument that caused the error */
-};
-
-static struct errs errs[ERRMAX];
-static int errcnt;
+struct errs errs[ERRMAX];
+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.";
@@ -270,8 +225,8 @@ str_addarg(char *str, size_t len, char *arg, int first)
static int
err_compar(const void *e1, const void *e2)
{
- const struct errs *p1 = (struct errs *) e1;
- const struct errs *p2 = (struct errs *) e2;
+ const struct errs *p1 = (const struct errs *) e1;
+ const struct errs *p2 = (const struct errs *) e2;
int result;
if ((result = p1->err - p2->err) == 0)
@@ -289,23 +244,6 @@ error_count(void)
}
/*
- * show_errors() - display on stdout the current log of errors.
- */
-void
-show_errors(void)
-{
- struct errs *errp = errs;
- int cnt = 0;
-
- printf("%d error%s:\n\n", errcnt, errcnt == 1 ? "" : "s");
- while (cnt++ < errcnt) {
- printf("%5s: %s\n", errp->arg,
- errp->err == 0 ? "Not a number" : strerror(errp->err));
- errp++;
- }
-}
-
-/*
* kill_procs(str) - send signals to processes, much like the "kill"
* command does; invoked in response to 'k'.
*/
diff --git a/usr.bin/top/display.c b/usr.bin/top/display.c
index 19d0dcfc980..8d0c09d746e 100644
--- a/usr.bin/top/display.c
+++ b/usr.bin/top/display.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: display.c,v 1.24 2007/03/30 19:21:19 otto Exp $ */
+/* $OpenBSD: display.c,v 1.25 2007/05/29 00:56:56 otto Exp $ */
/*
* Top users/processes display for Unix
@@ -47,15 +47,15 @@
#include <sys/types.h>
#include <sys/sched.h>
+#include <curses.h>
+#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <err.h>
+#include <signal.h>
#include <stdlib.h>
#include <string.h>
-#include <signal.h>
-#include <term.h>
#include <unistd.h>
-#include <stdarg.h>
#include "screen.h" /* interface to screen package */
#include "layout.h" /* defines for screen position layout */
@@ -70,14 +70,12 @@ FILE *debug;
#endif
static pid_t lmpid = 0;
-static int last_hi = 0; /* used in u_process and u_endscreen */
-static int lastline = 0;
static int display_width = MAX_COLS;
static char *cpustates_tag(int);
static int string_count(char **);
static void summary_format(char *, size_t, int *, char **);
-static void line_update(char *, char *, int, int);
+static int readlinedumb(char *, int, int);
#define lineindex(l) ((l)*display_width)
@@ -112,15 +110,28 @@ static enum {
OFF, ON, ERASE
} header_status = ON;
+static int
+empty(void)
+{
+ return OK;
+}
+
+static int
+myfputs(const char *s)
+{
+ return fputs(s, stdout);
+}
+
+static int (*addstrp)(const char *);
+static int (*printwp)(const char *, ...);
+static int (*standoutp)(void);
+static int (*standendp)(void);
+
int
display_resize(void)
{
int display_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 */
display_lines = smart_terminal ? screen_length - Header_lines : 1;
@@ -134,11 +145,6 @@ display_resize(void)
if (display_width >= MAX_COLS)
display_width = MAX_COLS - 1;
- /* now, allocate space for the screen buffer */
- screenbuf = malloc(display_lines * display_width + 1);
- if (screenbuf == NULL)
- return (-1);
-
/* return number of lines available */
/* for dumb terminals, pretend like we can show any amount */
return (smart_terminal ? display_lines : Largest);
@@ -150,6 +156,18 @@ display_init(struct statics * statics)
int display_lines, *ip, i, cpu;
char **pp;
+ if (smart_terminal) {
+ addstrp = addstr;
+ printwp = (int(*)(const char *, ...))printw;
+ standoutp = standout;
+ standendp = standend;
+ } else {
+ addstrp = myfputs;
+ printwp = printf;
+ standoutp = empty;
+ standendp = empty;
+ }
+
y_mem = 2 + ncpu;
y_message = 3 + ncpu;
y_header = 4 + ncpu;
@@ -206,47 +224,21 @@ i_loadave(pid_t mpid, double *avenrun)
{
int i;
- /* i_loadave also clears the screen, since it is first */
- clear();
+ move(0, 0);
+ clrtoeol();
/* mpid == -1 implies this system doesn't have an _mpid */
if (mpid != -1)
- printf("last pid: %5ld; ", (long) mpid);
+ printwp("last pid: %5ld; ", (long) mpid);
- printf("load averages");
+ addstrp("load averages");
for (i = 0; i < 3; i++)
- printf("%c %5.2f", i == 0 ? ':' : ',', avenrun[i]);
+ printwp("%c %5.2f", i == 0 ? ':' : ',', avenrun[i]);
lmpid = mpid;
}
-void
-u_loadave(pid_t mpid, double *avenrun)
-{
- int i;
-
- if (mpid != -1) {
- /* change screen only when value has really changed */
- if (mpid != lmpid) {
- Move_to(x_lastpid, y_lastpid);
- printf("%5ld", (long) 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]);
-}
-
/*
* Display the current time.
* "ctime" always returns a string that looks like this:
@@ -263,7 +255,7 @@ i_timeofday(time_t * tod)
{
if (smart_terminal) {
- Move_to(screen_width - 8, 0);
+ move(0, screen_width - 8);
} else {
if (fputs(" ", stdout) == EOF)
exit(1);
@@ -272,17 +264,13 @@ i_timeofday(time_t * tod)
{
char *foo;
foo = ctime(tod);
- if (fputs(foo, stdout) == EOF)
- exit(1);
+ addstrp(foo);
}
#endif
- printf("%-8.8s\n", &(ctime(tod)[11]));
- lastline = 1;
+ printwp("%-8.8s", &(ctime(tod)[11]));
+ putn();
}
-static int ltotal = 0;
-static char procstates_buffer[MAX_COLS];
-
/*
* *_procstates(total, brkdn, names) - print the process summary line
*
@@ -293,67 +281,30 @@ void
i_procstates(int total, int *brkdn)
{
int i;
+ char procstates_buffer[MAX_COLS];
+ move(1, 0);
+ clrtoeol();
/* write current number of processes and remember the value */
- printf("%d processes:", total);
- ltotal = total;
-
- /* put out enough spaces to get to column 15 */
- i = digits(total);
- while (i++ < 4) {
- if (putchar(' ') == EOF)
- exit(1);
+ printwp("%d processes:", total);
+
+ if (smart_terminal)
+ move(1, 15);
+ else {
+ /* put out enough spaces to get to column 15 */
+ i = digits(total);
+ while (i++ < 4) {
+ if (putchar(' ') == EOF)
+ exit(1);
+ }
}
/* format and print the process state summary */
summary_format(procstates_buffer, sizeof(procstates_buffer), brkdn,
procstate_names);
- if (fputs(procstates_buffer, stdout) == EOF)
- exit(1);
-
- /* save the numbers for next time */
- memcpy(lprocstates, brkdn, num_procstates * sizeof(int));
-}
-
-void
-u_procstates(int total, int *brkdn)
-{
- static char new[MAX_COLS];
- int i;
-
- /* update number of processes only if it has changed */
- if (ltotal != total) {
- /* move and overwrite */
-#if (x_procstate == 0)
- Move_to(x_procstate, y_procstate);
-#else
- /* cursor is already there...no motion needed */
- /* assert(lastline == 1); */
-#endif
- printf("%d", total);
- /* if number of digits differs, rewrite the label */
- if (digits(total) != digits(ltotal)) {
- if (fputs(" processes:", stdout) == EOF)
- exit(1);
- /* put out enough spaces to get to column 15 */
- i = digits(total);
- while (i++ < 4) {
- if (putchar(' ') == EOF)
- exit(1);
- }
- /* cursor may end up right where we want it!!! */
- }
- /* save new total */
- ltotal = total;
- }
- /* see if any of the state numbers has changed */
- if (memcmp(lprocstates, brkdn, num_procstates * sizeof(int)) != 0) {
- /* format and update the line */
- summary_format(new, sizeof(new), brkdn, procstate_names);
- line_update(procstates_buffer, new, x_brkdn, y_brkdn);
- memcpy(lprocstates, brkdn, num_procstates * sizeof(int));
- }
+ addstrp(procstates_buffer);
+ putn();
}
/*
@@ -362,8 +313,6 @@ u_procstates(int total, int *brkdn)
* Assumptions: cursor is on the PREVIOUS line
*/
-static int cpustates_column;
-
/* cpustates_tag() calculates the correct tag to use to label the line */
static char *
@@ -397,10 +346,8 @@ cpustates_tag(int cpu)
i = asprintf(&tag, "CPU%.*d states: ", cpulen, cpu);
if (i == -1)
tag = NULL;
- else {
- cpustates_column = strlen(tag);
+ else
old_width = screen_width;
- }
}
return (tag);
}
@@ -413,9 +360,10 @@ i_cpustates(int64_t *ostates)
char **names = cpustate_names, *thisname;
for (cpu = 0; cpu < ncpu; cpu++) {
+ move(2 + cpu, 0);
+ clrtoeol();
/* print tag and bump lastline */
- printf("\n%s", cpustates_tag(cpu));
- lastline++;
+ addstrp(cpustates_tag(cpu));
/* now walk thru the names and print the line */
names = cpustate_names;
@@ -427,65 +375,15 @@ i_cpustates(int64_t *ostates)
value = *states++;
/* if percentage is >= 1000, print it as 100% */
- printf((value >= 1000 ? "%s%4.0f%% %s" :
+ printwp((value >= 1000 ? "%s%4.0f%% %s" :
"%s%4.1f%% %s"), i++ == 0 ? "" : ", ",
((float) value) / 10., thisname);
}
}
-
- /* copy over values into "last" array */
- memcpy(lcpustates[cpu], ostates, num_cpustates * sizeof(int64_t));
+ putn();
}
}
-void
-u_cpustates(int64_t *ostates)
-{
- char **names, *thisname;
- int cpu, value, *colp;
- int64_t *lp, *states;
-
- for (cpu = 0; cpu < ncpu; cpu++) {
- lastline = y_cpustates + cpu;
- states = ostates + (CPUSTATES * cpu);
- Move_to(cpustates_column, lastline);
- lp = lcpustates[cpu];
- colp = cpustate_columns;
-
- /* we could be much more optimal about this */
- names = cpustate_names;
- while ((thisname = *names++) != NULL) {
- if (*thisname != '\0') {
- /* did the value change since last time? */
- if (*lp != *states) {
- /* yes, move and change */
- lastline = y_cpustates + cpu;
- Move_to(cpustates_column + *colp,
- lastline);
-
- /* retrieve value and remember it */
- value = *states;
-
- /* if percentage is >= 1000,
- * print it as 100%
- */
- printf((value >= 1000 ? "%4.0f" :
- "%4.1f"), ((double) value) / 10.);
-
- /* remember it for next time */
- *lp = *states;
- }
- }
- /* increment and move on */
- lp++;
- states++;
- colp++;
- }
- }
-}
-
-static char memory_buffer[MAX_COLS];
-
/*
* *_memory(stats) - print "Memory: " followed by the memory summary string
*
@@ -495,25 +393,17 @@ static char memory_buffer[MAX_COLS];
void
i_memory(int *stats)
{
- if (fputs("\nMemory: ", stdout) == EOF)
- exit(1);
- lastline++;
+ char memory_buffer[MAX_COLS];
+
+ move(y_mem, 0);
+ clrtoeol();
+ addstrp("Memory: ");
/* format and print the memory summary */
summary_format(memory_buffer, sizeof(memory_buffer), stats,
memory_names);
- if (fputs(memory_buffer, stdout) == EOF)
- exit(1);
-}
-
-void
-u_memory(int *stats)
-{
- static char new[MAX_COLS];
-
- /* format the new line */
- summary_format(new, sizeof(new), stats, memory_names);
- line_update(memory_buffer, new, x_mem, y_mem);
+ addstrp(memory_buffer);
+ putn();
}
/*
@@ -540,27 +430,27 @@ static int msglen = 0;
void
i_message(void)
{
+ /*
while (lastline < y_message) {
if (fputc('\n', stdout) == EOF)
exit(1);
lastline++;
}
+ */
+ move(y_message, 0);
if (next_msg[0] != '\0') {
- standout(next_msg);
+ standoutp();
+ addstrp(next_msg);
+ standendp();
+ clrtoeol();
msglen = strlen(next_msg);
next_msg[0] = '\0';
} else if (msglen > 0) {
- (void) clear_eol(msglen);
+ clrtoeol();
msglen = 0;
}
}
-void
-u_message(void)
-{
- i_message();
-}
-
static int header_length;
/*
@@ -574,29 +464,21 @@ i_header(char *text)
{
header_length = strlen(text);
if (header_status == ON) {
- if (putchar('\n') == EOF)
- exit(1);
- if (fputs(text, stdout) == EOF)
- exit(1);
- lastline++;
+ if (!smart_terminal) {
+ putn();
+ if (fputs(text, stdout) == EOF)
+ exit(1);
+ putn();
+ } else {
+ move(y_header, 0);
+ clrtoeol();
+ addstrp(text);
+ }
} else if (header_status == ERASE) {
header_status = OFF;
}
}
-/* ARGSUSED */
-void
-u_header(char *text)
-{
- if (header_status == ERASE) {
- if (putchar('\n') == EOF)
- exit(1);
- lastline++;
- clear_eol(header_length);
- header_status = OFF;
- }
-}
-
/*
* *_process(line, thisline) - print one process line
*
@@ -604,122 +486,31 @@ u_header(char *text)
*/
void
-i_process(int line, char *thisline)
+i_process(int line, char *thisline, int hl)
{
- char *base;
- size_t len;
-
/* make sure we are on the correct line */
- while (lastline < y_procs + line) {
- if (putchar('\n') == EOF)
- exit(1);
- lastline++;
- }
+ move(y_procs + line, 0);
/* truncate the line to conform to our current screen width */
thisline[display_width] = '\0';
/* write the line out */
- if (fputs(thisline, stdout) == EOF)
- exit(1);
-
- /* copy it in to our buffer */
- base = smart_terminal ? screenbuf + lineindex(line) : screenbuf;
- len = strlcpy(base, thisline, display_width);
- if (len < (size_t)display_width) {
- /* zero fill the rest of it */
- memset(base + len, 0, display_width - len);
- }
-}
-
-void
-u_process(int linenum, char *linebuf)
-{
- int screen_line = linenum + Header_lines;
- char *bufferline;
- size_t len;
-
- /* remember a pointer to the current line in the screen buffer */
- bufferline = &screenbuf[lineindex(linenum)];
-
- /* truncate the line to conform to our current screen width */
- linebuf[display_width] = '\0';
- bufferline[display_width] = '\0';
-
- /* is line higher than we went on the last display? */
- if (linenum >= last_hi) {
- /* yes, just ignore screenbuf and write it out directly */
- /* get positioned on the correct line */
- if (screen_line - lastline == 1) {
- if (putchar('\n') == EOF)
- exit(1);
- lastline++;
- } else {
- Move_to(0, screen_line);
- lastline = screen_line;
- }
-
- /* now write the line */
- if (fputs(linebuf, stdout) == EOF)
- exit(1);
-
- /* copy it in to the buffer */
- len = strlcpy(bufferline, linebuf, display_width);
- if (len < (size_t)display_width) {
- /* zero fill the rest of it */
- memset(bufferline + len, 0, display_width - len);
- }
- } else {
- line_update(bufferline, linebuf, 0, linenum + Header_lines);
- }
+ if (hl && smart_terminal)
+ standoutp();
+ addstrp(thisline);
+ if (hl && smart_terminal)
+ standendp();
+ putn();
+ clrtoeol();
}
void
u_endscreen(int hi)
{
- int screen_line = hi + Header_lines, i;
-
if (smart_terminal) {
- if (hi < last_hi) {
- /* need to blank the remainder of the screen */
- /*
- * but only if there is any screen left below this
- * line
- */
- if (lastline + 1 < screen_length) {
- /*
- * efficiently move to the end of currently
- * displayed info
- */
- if (screen_line - lastline < 5) {
- while (lastline < screen_line) {
- if (putchar('\n') == EOF)
- exit(1);
- lastline++;
- }
- } else {
- Move_to(0, screen_line);
- lastline = screen_line;
- }
-
- if (clear_to_end) {
- /* we can do this the easy way */
- putcap(clear_to_end);
- } else {
- /* use clear_eol on each line */
- i = hi;
- while ((void) clear_eol(strlen(&screenbuf[lineindex(i++)])), i < last_hi) {
- if (putchar('\n') == EOF)
- exit(1);
- }
- }
- }
- }
- last_hi = hi;
-
+ clrtobot();
/* move the cursor to a pleasant place */
- Move_to(x_idlecursor, y_idlecursor);
- lastline = y_idlecursor;
+ move(y_idlecursor, x_idlecursor);
} else {
/*
* separate this display from the next with some vertical
@@ -753,46 +544,46 @@ new_message(int type, const char *msgfmt,...)
if (msglen > 0) {
/* message there already -- can we clear it? */
- if (!overstrike) {
- /* yes -- write it and clear to end */
- i = strlen(next_msg);
- if ((type & MT_delayed) == 0) {
- if (type & MT_standout)
- standout(next_msg);
- else {
- if (fputs(next_msg, stdout) == EOF)
- exit(1);
- }
- (void) clear_eol(msglen - i);
- msglen = i;
- next_msg[0] = '\0';
- }
+ /* yes -- write it and clear to end */
+ i = strlen(next_msg);
+ if ((type & MT_delayed) == 0) {
+ move(y_message, 0);
+ if (type & MT_standout)
+ standoutp();
+ addstrp(next_msg);
+ if (type & MT_standout)
+ standendp();
+ clrtoeol();
+ msglen = i;
+ next_msg[0] = '\0';
}
} else {
if ((type & MT_delayed) == 0) {
+ move(y_message, 0);
if (type & MT_standout)
- standout(next_msg);
- else {
- if (fputs(next_msg, stdout) == EOF)
- exit(1);
- }
+ standoutp();
+ addstrp(next_msg);
+ if (type & MT_standout)
+ standendp();
+ clrtoeol();
msglen = strlen(next_msg);
next_msg[0] = '\0';
}
}
+ if (smart_terminal)
+ refresh();
}
void
clear_message(void)
{
- if (clear_eol(msglen) == 1) {
- if (putchar('\r') == EOF)
- exit(1);
- }
+ move(y_message, 0);
+ clrtoeol();
}
-int
-readline(char *buffer, int size, int numeric)
+
+static int
+readlinedumb(char *buffer, int size, int numeric)
{
char *ptr = buffer, ch, cnt = 0, maxcnt = 0;
extern volatile sig_atomic_t leaveflag;
@@ -815,14 +606,9 @@ readline(char *buffer, int size, int numeric)
/* handle special editing characters */
if (ch == ch_kill) {
- /* kill line -- account for overstriking */
- if (overstrike)
- msglen += maxcnt;
-
/* return null string */
*buffer = '\0';
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
return (-1);
} else if (ch == ch_erase) {
/* erase previous character */
@@ -858,12 +644,29 @@ readline(char *buffer, int size, int numeric)
*ptr = '\0';
/* account for the extra characters in the message area */
- /* (if terminal overstrikes, remember the furthest they went) */
- msglen += overstrike ? maxcnt : cnt;
+ msglen += cnt;
/* return either inputted number or string length */
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
+ return (cnt == 0 ? -1 : numeric ? atoi(buffer) : cnt);
+}
+
+int
+readline(char *buffer, int size, int numeric)
+{
+ size_t cnt;
+
+ /* allow room for null terminator */
+ size -= 1;
+
+ if (smart_terminal)
+ getnstr(buffer, size);
+ else
+ return readlinedumb(buffer, size, numeric);
+
+ cnt = strlen(buffer);
+ if (cnt > 0 && buffer[cnt - 1] == '\n')
+ buffer[cnt - 1] = '\0';
return (cnt == 0 ? -1 : numeric ? atoi(buffer) : cnt);
}
@@ -934,108 +737,6 @@ summary_format(char *buf, size_t left, int *numbers, char **names)
*p = '\0';
}
-static void
-line_update(char *old, char *new, int start, int line)
-{
- int ch, diff, newcol = start + 1, lastcol = start;
- char cursor_on_line = No, *current;
-
- /* compare the two strings and only rewrite what has changed */
- current = old;
-#ifdef DEBUG
- fprintf(debug, "line_update, starting at %d\n", start);
- fputs(old, debug);
- fputc('\n', debug);
- fputs(new, debug);
- fputs("\n-\n", debug);
-#endif
-
- /* start things off on the right foot */
- /* this is to make sure the invariants get set up right */
- if ((ch = *new++) != *old) {
- if (line - lastline == 1 && start == 0) {
- if (putchar('\n') == EOF)
- exit(1);
- } else
- Move_to(start, line);
-
- cursor_on_line = Yes;
- if (putchar(ch) == EOF)
- exit(1);
- *old = ch;
- lastcol = 1;
- }
- old++;
-
- /*
- * main loop -- check each character. If the old and new aren't the
- * same, then update the display. When the distance from the
- * current cursor position to the new change is small enough,
- * the characters that belong there are written to move the
- * cursor over.
- *
- * Invariants:
- * lastcol is the column where the cursor currently is sitting
- * (always one beyond the end of the last mismatch).
- */
- do {
- if ((ch = *new++) != *old) {
- /* new character is different from old */
- /* make sure the cursor is on top of this character */
- diff = newcol - lastcol;
- if (diff > 0) {
- /*
- * some motion is required--figure out which
- * is shorter
- */
- if (diff < 6 && cursor_on_line) {
- /*
- * overwrite old stuff--get it out of
- * the old buffer
- */
- printf("%.*s", diff, &current[lastcol - start]);
- } else {
- /* use cursor addressing */
- Move_to(newcol, line);
- cursor_on_line = Yes;
- }
- /* remember where the cursor is */
- lastcol = newcol + 1;
- } else {
- /* already there, update position */
- lastcol++;
- }
-
- /* write what we need to */
- if (ch == '\0') {
- /*
- * at the end--terminate with a
- * clear-to-end-of-line
- */
- (void) clear_eol(strlen(old));
- } else {
- /* write the new character */
- if (putchar(ch) == EOF)
- exit(1);
- }
- /* put the new character in the screen buffer */
- *old = ch;
- }
- /* update working column and screen buffer pointer */
- newcol++;
- old++;
- } while (ch != '\0');
-
- /* zero out the rest of the line buffer -- MUST BE DONE! */
- diff = display_width - newcol;
- if (diff > 0)
- memset(old, 0, diff);
-
- /* remember where the current line is */
- if (cursor_on_line)
- lastline = line;
-}
-
/*
* printable(str) - make the string pointed to by "str" into one that is
* printable (i.e.: all ascii), by converting all non-printable
@@ -1055,3 +756,92 @@ printable(char *str)
}
return (str);
}
+
+
+/*
+ * show_help() - display the help screen; invoked in response to
+ * either 'h' or '?'.
+ */
+void
+show_help(void)
+{
+ if (smart_terminal) {
+ clear();
+ nl();
+ }
+ printwp("These single-character commands are available:\n"
+ "\n"
+ "^L - redraw screen\n"
+ "+ - reset any g, p, or u filters\n"
+ "C - toggle the display of command line arguments\n"
+ "d count - show `count' displays, then exit\n"
+ "e - list errors generated by last \"kill\" or \"renice\" command\n"
+ "h | ? - help; show this text\n"
+ "g string - filter on command name (g+ selects all commands)\n"
+ "I | i - toggle the display of idle processes\n"
+ "k [-sig] pid - send signal `-sig' to process `pid'\n"
+ "n|# count - show `count' processes\n"
+ "o field - specify sort order (size, res, cpu, time, pri)\n"
+ "P pid - highlight process `pid' (P+ switches highlighting off)\n"
+ "p pid - display process by `pid' (p+ selects all processes)\n"
+ "q - quit\n"
+ "r count pid - renice process `pid' to nice value `count'\n"
+ "S - toggle the display of system processes\n"
+ "s time - change delay between displays to `time' seconds\n"
+ "T - toggle the display of threads\n"
+ "u user - display processes for `user' (u+ selects all users)\n"
+ "\n");
+
+ if (smart_terminal) {
+ nonl();
+ refresh();
+ }
+}
+
+/*
+ * show_errors() - display on stdout the current log of errors.
+ */
+void
+show_errors(void)
+{
+ struct errs *errp = errs;
+ int cnt = 0;
+
+ if (smart_terminal) {
+ clear();
+ nl();
+ }
+ printwp("%d error%s:\n\n", errcnt, errcnt == 1 ? "" : "s");
+ while (cnt++ < errcnt) {
+ printf("%5s: %s\n", errp->arg,
+ errp->err == 0 ? "Not a number" : strerror(errp->err));
+ errp++;
+ }
+ if (smart_terminal) {
+ nonl();
+ refresh();
+ }
+}
+
+void
+anykey(void)
+{
+ int ch;
+ size_t len;
+
+ standoutp();
+ addstrp("Hit any key to continue: ");
+ standendp();
+ if (smart_terminal)
+ refresh();
+ else
+ fflush(stdout);
+ while (1) {
+ len = read(STDIN_FILENO, &ch, 1);
+ if (len == -1 && errno == EINTR)
+ continue;
+ if (len == 0)
+ exit(1);
+ break;
+ }
+}
diff --git a/usr.bin/top/display.h b/usr.bin/top/display.h
index ffa9dc899da..782f646fc06 100644
--- a/usr.bin/top/display.h
+++ b/usr.bin/top/display.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: display.h,v 1.8 2006/03/04 06:58:12 otto Exp $ */
+/* $OpenBSD: display.h,v 1.9 2007/05/29 00:56:56 otto Exp $ */
/*
* Top users/processes display for Unix
@@ -34,25 +34,32 @@
#define MT_delayed 2
/* prototypes */
-extern int display_resize(void);
-extern void i_loadave(int, double *);
-extern void u_loadave(int, double *);
-extern void i_timeofday(time_t *);
-extern void i_procstates(int, int *);
-extern void u_procstates(int, int *);
-extern void i_cpustates(int64_t *);
-extern void u_cpustates(int64_t *);
-extern void i_memory(int *);
-extern void u_memory(int *);
-extern void i_message(void);
-extern void u_message(void);
-extern void i_header(char *);
-extern void u_header(char *);
-extern void i_process(int, char *);
-extern void u_process(int, char *);
-extern void u_endscreen(int);
-extern void display_header(int);
-extern void new_message(int, const char *, ...);
-extern void clear_message(void);
-extern int readline(char *, int, int);
-extern char *printable(char *);
+int display_resize(void);
+void i_loadave(int, double *);
+void u_loadave(int, double *);
+void i_timeofday(time_t *);
+void i_procstates(int, int *);
+void u_procstates(int, int *);
+void i_cpustates(int64_t *);
+void u_cpustates(int64_t *);
+void i_memory(int *);
+void u_memory(int *);
+void i_message(void);
+void u_message(void);
+void i_header(char *);
+void u_header(char *);
+void i_process(int, char *, int);
+void u_process(int, char *, int);
+void u_endscreen(int);
+void display_header(int);
+void new_message(int, const char *, ...);
+void clear_message(void);
+int readline(char *, int, int);
+char *printable(char *);
+void show_help(void);
+void anykey(void);
+
+#define putr() do { if (!smart_terminal) if (putchar('\r') == EOF) exit(1); } \
+ while (0)
+#define putn() do { if (!smart_terminal) if (putchar('\n') == EOF) exit(1); } \
+ while (0)
diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c
index 1dc9162f0bb..58059465974 100644
--- a/usr.bin/top/machine.c
+++ b/usr.bin/top/machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machine.c,v 1.60 2007/04/16 11:49:51 otto Exp $ */
+/* $OpenBSD: machine.c,v 1.61 2007/05/29 00:56:56 otto Exp $ */
/*-
* Copyright (c) 1994 Thorsten Lockert <tholo@sigmasoft.com>
@@ -459,7 +459,7 @@ format_comm(struct kinfo_proc2 *kp)
}
char *
-format_next_process(caddr_t handle, char *(*get_userid)(uid_t))
+format_next_process(caddr_t handle, char *(*get_userid)(uid_t), pid_t *pid)
{
char *p_wait, waddr[sizeof(void *) * 2 + 3]; /* Hexify void pointer */
struct kinfo_proc2 *pp;
@@ -499,6 +499,7 @@ format_next_process(caddr_t handle, char *(*get_userid)(uid_t))
p_wait, format_time(cputime), 100.0 * pct,
printable(format_comm(pp)));
+ *pid = pp->p_pid;
/* return the result */
return (fmt);
}
diff --git a/usr.bin/top/machine.h b/usr.bin/top/machine.h
index cce60e2f106..55aee794e95 100644
--- a/usr.bin/top/machine.h
+++ b/usr.bin/top/machine.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: machine.h,v 1.14 2005/12/04 23:10:06 tedu Exp $ */
+/* $OpenBSD: machine.h,v 1.15 2007/05/29 00:56:56 otto Exp $ */
/*
* Top users/processes display for Unix
@@ -88,7 +88,7 @@ extern void get_system_info(struct system_info *);
extern caddr_t
get_process_info(struct system_info *, struct process_select *,
int (*) (const void *, const void *));
-extern char *format_next_process(caddr_t, char *(*)(uid_t));
+extern char *format_next_process(caddr_t, char *(*)(uid_t), pid_t *);
extern uid_t proc_owner(pid_t);
extern struct kinfo_proc2 *getprocs(int, int, int *);
diff --git a/usr.bin/top/screen.c b/usr.bin/top/screen.c
index a3ac369e10d..847bb0111dc 100644
--- a/usr.bin/top/screen.c
+++ b/usr.bin/top/screen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen.c,v 1.16 2007/04/04 19:12:15 otto Exp $ */
+/* $OpenBSD: screen.c,v 1.17 2007/05/29 00:56:56 otto Exp $ */
/*
* Top users/processes display for Unix
@@ -40,10 +40,10 @@
#include <sys/types.h>
#include <sys/ioctl.h>
+#include <curses.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <term.h>
#include <unistd.h>
@@ -51,21 +51,16 @@
#include "screen.h"
#include "boolean.h"
-int overstrike, screen_length, screen_width;
-char ch_erase, ch_kill, smart_terminal, PC;
-char string_buffer[1024], home[15], lower_left[15];
-char *clear_line, *clear_scr, *clear_to_end;
-char *cursor_motion, *start_standout, *end_standout;
-char *terminal_init, *terminal_end;
+int screen_length, screen_width;
+char ch_erase, ch_kill, smart_terminal;
static struct termios old_settings, new_settings;
-
-static char is_a_terminal = No;
+static char is_a_terminal = No;
void
init_termcap(int interactive)
{
- char *bufptr, *PCptr, *term_name;
+ char *term_name;
int status;
/* set defaults in case we aren't smart */
@@ -107,6 +102,7 @@ init_termcap(int interactive)
smart_terminal = No;
return;
}
+
/* set up common terminal capabilities */
if ((screen_length = tgetnum("li")) <= Header_lines) {
screen_length = smart_terminal = 0;
@@ -119,35 +115,11 @@ init_termcap(int interactive)
else
screen_width -= 1;
- /* terminals that overstrike need special attention */
- overstrike = tgetflag("os");
-
- /* initialize the pointer into the termcap string buffer */
- bufptr = string_buffer;
-
- /* get "ce", clear to end */
- if (!overstrike) {
- clear_line = tgetstr("ce", &bufptr);
- }
- /* get necessary capabilities */
- if ((clear_scr = tgetstr("cl", &bufptr)) == NULL ||
- (cursor_motion = tgetstr("cm", &bufptr)) == NULL) {
- smart_terminal = No;
- return;
- }
- /* get some more sophisticated stuff -- these are optional */
- clear_to_end = tgetstr("cd", &bufptr);
- terminal_init = tgetstr("ti", &bufptr);
- terminal_end = tgetstr("te", &bufptr);
- start_standout = tgetstr("so", &bufptr);
- end_standout = tgetstr("se", &bufptr);
-
- /* pad character */
- PC = (PCptr = tgetstr("pc", &bufptr)) ? *PCptr : 0;
-
- /* set convenience strings */
- (void) strlcpy(home, tgoto(cursor_motion, 0, 0), sizeof(home));
- /* (lower_left is set in get_screensize) */
+ /* get necessary capabilities */
+ if (tgetstr("cl", NULL) == NULL || tgetstr("cm", NULL) == NULL) {
+ smart_terminal = No;
+ return;
+ }
/* get the actual screen size with an ioctl, if needed */
/*
@@ -168,42 +140,37 @@ init_screen(void)
if (tcgetattr(STDOUT_FILENO, &old_settings) != -1) {
/* copy the settings so we can modify them */
new_settings = old_settings;
-
/* turn off ICANON, character echo and tab expansion */
new_settings.c_lflag &= ~(ICANON | ECHO);
new_settings.c_oflag &= ~(OXTABS);
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
- (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);
+ (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);
/* remember the erase and kill characters */
ch_erase = old_settings.c_cc[VERASE];
ch_kill = old_settings.c_cc[VKILL];
- /* remember that it really is a terminal */
is_a_terminal = Yes;
-
+#if 0
/* send the termcap initialization string */
putcap(terminal_init);
+#endif
}
if (!is_a_terminal) {
/* not a terminal at all---consider it dumb */
smart_terminal = No;
}
+
+ if (smart_terminal)
+ initscr();
}
void
end_screen(void)
{
- /* move to the lower left, clear the line and send "te" */
- if (smart_terminal) {
- putcap(lower_left);
- putcap(clear_line);
- fflush(stdout);
- putcap(terminal_end);
- }
-
- /* if we have settings to reset, then do so */
+ if (smart_terminal)
+ endwin();
if (is_a_terminal)
(void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &old_settings);
}
@@ -211,6 +178,7 @@ end_screen(void)
void
reinit_screen(void)
{
+#if 0
/* install our settings if it is a terminal */
if (is_a_terminal)
(void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);
@@ -218,6 +186,7 @@ reinit_screen(void)
/* send init string */
if (smart_terminal)
putcap(terminal_init);
+#endif
}
void
@@ -231,54 +200,15 @@ get_screensize(void)
if (ws.ws_col != 0)
screen_width = ws.ws_col - 1;
}
- (void) strlcpy(lower_left, tgoto(cursor_motion, 0, screen_length - 1),
- sizeof(lower_left));
}
void
-standout(char *msg)
+go_home(void)
{
if (smart_terminal) {
- putcap(start_standout);
- if (fputs(msg, stdout) == EOF)
- exit(1);
- putcap(end_standout);
- } else {
- if (fputs(msg, stdout) == EOF)
- exit(1);
- }
-}
-
-void
-clear(void)
-{
- if (smart_terminal)
- putcap(clear_scr);
-}
-
-int
-clear_eol(int len)
-{
- if (smart_terminal && !overstrike && len > 0) {
- if (clear_line) {
- putcap(clear_line);
- return (0);
- } else {
- while (len-- > 0) {
- if (putchar(' ') == EOF)
- exit(1);
- }
- return (1);
- }
+ move(0, 0);
+ refresh();
}
- return (-1);
-}
-
-void
-go_home(void)
-{
- if (smart_terminal)
- putcap(home);
}
/* This has to be defined as a subroutine for tputs (instead of a macro) */
diff --git a/usr.bin/top/screen.h b/usr.bin/top/screen.h
index 309972ec8cb..1b1af60df4b 100644
--- a/usr.bin/top/screen.h
+++ b/usr.bin/top/screen.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen.h,v 1.4 2002/07/15 17:20:36 deraadt Exp $ */
+/* $OpenBSD: screen.h,v 1.5 2007/05/29 00:56:56 otto Exp $ */
/*
* Top users/processes display for Unix
@@ -35,19 +35,12 @@
* screen package in "screen.c"
*/
-#define TCputs(str) tputs(str, 1, putstdout)
-#define putcap(str) (void)((str) != NULL ? TCputs(str) : 0)
-#define Move_to(x, y) TCputs(tgoto(cursor_motion, x, y))
-
extern char ch_erase; /* set to the user's erase character */
extern char ch_kill; /* set to the user's kill character */
extern char smart_terminal; /* set if the terminal has sufficient termcap
capabilities for normal operation */
/* These are some termcap strings for use outside of "screen.c" */
-extern char *cursor_motion;
-extern char *clear_line;
-extern char *clear_to_end;
/* rows and columns on the screen according to termcap */
extern int screen_length;
@@ -59,8 +52,5 @@ extern void init_screen(void);
extern void end_screen(void);
extern void reinit_screen(void);
extern void get_screensize(void);
-extern void standout(char *);
-extern void clear(void);
-extern int clear_eol(int);
extern void go_home(void);
extern int putstdout(int);
diff --git a/usr.bin/top/top.1 b/usr.bin/top/top.1
index 35d9c099367..e4721094701 100644
--- a/usr.bin/top/top.1
+++ b/usr.bin/top/top.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: top.1,v 1.45 2007/03/15 22:02:22 jmc Exp $
+.\" $OpenBSD: top.1,v 1.46 2007/05/29 00:56:56 otto Exp $
.\"
.\" Copyright (c) 1997, Jason Downs. All rights reserved.
.\"
@@ -263,8 +263,6 @@ Redraw the screen.
Quit
.Nm .
.El
-.Pp
-The following commands may not be available with overstrike terminals:
.Bl -tag -width XxXXXX
.It +
Reset any filters put in place by the
@@ -317,6 +315,9 @@ as the primary key.
Values are the same as for the
.Fl o
flag, as detailed above.
+.It P Ar pid
+Highlight a specific process, selected by
+.Ar pid .
.It p Ar pid
Show only the process
.Ar pid .
diff --git a/usr.bin/top/top.c b/usr.bin/top/top.c
index 7aa9bd21607..eb9ab5765ee 100644
--- a/usr.bin/top/top.c
+++ b/usr.bin/top/top.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: top.c,v 1.50 2007/04/01 19:07:48 jmc Exp $ */
+/* $OpenBSD: top.c,v 1.51 2007/05/29 00:56:56 otto Exp $ */
/*
* Top users/processes display for Unix
@@ -28,21 +28,17 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-const char copyright[] = "Copyright (c) 1984 through 1996, William LeFebvre";
-
#include <sys/types.h>
-#include <sys/time.h>
+#include <curses.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
-#include <ctype.h>
#include <signal.h>
#include <string.h>
#include <poll.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
-#include <sys/stat.h>
/* includes specific to top */
#include "display.h" /* interface to display package */
@@ -59,13 +55,11 @@ const char copyright[] = "Copyright (c) 1984 through 1996, William LeFebvre";
/* The buffer that stdio will use */
char stdoutbuf[BUFFERSIZE];
-extern int overstrike;
-
/* signal handling routines */
static void leave(int);
static void onalrm(int);
static void tstop(int);
-static void winch(int);
+static void sigwinch(int);
volatile sig_atomic_t leaveflag, tstopflag, winchflag;
@@ -77,15 +71,6 @@ static int max_topn; /* maximum displayable processes */
extern int (*proc_compares[])(const void *, const void *);
int order_index;
-/* pointers to display routines */
-void (*d_loadave)(int, double *) = i_loadave;
-void (*d_procstates)(int, int *) = i_procstates;
-void (*d_cpustates)(int64_t *) = i_cpustates;
-void (*d_memory)(int *) = i_memory;
-void (*d_message)(void) = i_message;
-void (*d_header)(char *) = i_header;
-void (*d_process)(int, char *) = i_process;
-
int displays = 0; /* indicates unspecified */
char do_unames = Yes;
struct process_select ps;
@@ -98,6 +83,7 @@ int no_command = Yes;
int old_system = No;
int old_threads = No;
int show_args = No;
+pid_t hlpid = -1;
#if Default_TOPN == Infinity
char topn_specified = No;
@@ -130,6 +116,7 @@ char topn_specified = No;
#define CMD_threads 19
#define CMD_grep 20
#define CMD_add 21
+#define CMD_hl 22
static void
usage(void)
@@ -405,7 +392,8 @@ main(int argc, char *argv[])
siginterrupt(SIGINT, 1);
(void) signal(SIGQUIT, leave);
(void) signal(SIGTSTP, tstop);
- (void) signal(SIGWINCH, winch);
+ if (smart_terminal)
+ (void) signal(SIGWINCH, sigwinch);
sigprocmask(SIG_SETMASK, &oldmask, NULL);
if (warnings) {
fputs("....", stderr);
@@ -428,7 +416,7 @@ restart:
proc_compares[order_index]);
/* display the load averages */
- (*d_loadave)(system_info.last_pid, system_info.load_avg);
+ i_loadave(system_info.last_pid, system_info.load_avg);
/* display the current time */
/* this method of getting the time SHOULD be fairly portable */
@@ -436,19 +424,19 @@ restart:
i_timeofday(&curr_time);
/* display process state breakdown */
- (*d_procstates)(system_info.p_total, system_info.procstates);
+ i_procstates(system_info.p_total, system_info.procstates);
/* display the cpu state percentage breakdown */
- (*d_cpustates)(system_info.cpustates);
+ i_cpustates(system_info.cpustates);
/* display memory stats */
- (*d_memory)(system_info.memory);
+ i_memory(system_info.memory);
/* handle message area */
- (*d_message)();
+ i_message();
/* update the header area */
- (*d_header)(header_text);
+ i_header(header_text);
if (topn > 0) {
/* determine number of processes to actually display */
@@ -463,9 +451,14 @@ restart:
if (active_procs > max_topn)
active_procs = max_topn;
/* now show the top "n" processes. */
- for (i = 0; i < active_procs; i++)
- (*d_process)(i, format_next_process(processes,
- get_userid));
+ for (i = 0; i < active_procs; i++) {
+ pid_t pid;
+ char * s;
+
+ s = format_next_process(processes, get_userid,
+ &pid);
+ i_process(i, s, pid == hlpid);
+ }
} else
i = 0;
@@ -475,22 +468,12 @@ restart:
/* now, flush the output buffer */
fflush(stdout);
+ if (smart_terminal)
+ refresh();
+
/* only do the rest if we have more displays to show */
if (displays) {
/* switch out for new display on smart terminals */
- if (smart_terminal) {
- if (overstrike) {
- reset_display();
- } else {
- d_loadave = u_loadave;
- d_procstates = u_procstates;
- d_cpustates = u_cpustates;
- d_memory = u_memory;
- d_message = u_message;
- d_header = u_header;
- d_process = u_process;
- }
- }
no_command = Yes;
if (!interactive) {
/* set up alarm */
@@ -530,7 +513,7 @@ rundisplay(void)
int change, i;
struct pollfd pfd[1];
uid_t uid;
- static char command_chars[] = "\f qh?en#sdkriIuSopCTg+";
+ static char command_chars[] = "\f qh?en#sdkriIuSopCTg+P";
/*
* assume valid command unless told
@@ -582,12 +565,13 @@ rundisplay(void)
* dimensions
*/
get_screensize();
+ resizeterm(screen_length, screen_width + 1);
/* tell display to resize */
max_topn = display_resize();
/* reset the signal handler */
- (void) signal(SIGWINCH, winch);
+ (void) signal(SIGWINCH, sigwinch);
reset_display();
winchflag = 0;
@@ -620,24 +604,13 @@ rundisplay(void)
if ((iptr = strchr(command_chars, ch)) == NULL) {
/* illegal command */
new_message(MT_standout, " Command not understood");
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
no_command = Yes;
fflush(stdout);
return (0);
}
change = iptr - command_chars;
- if (overstrike && change > CMD_OSLIMIT) {
- /* error */
- new_message(MT_standout,
- " Command cannot be handled by this terminal");
- if (putchar('\r') == EOF)
- exit(1);
- no_command = Yes;
- fflush(stdout);
- return (0);
- }
switch (change) {
case CMD_redraw: /* redraw screen */
@@ -661,42 +634,23 @@ rundisplay(void)
case CMD_help1: /* help */
case CMD_help2:
- reset_display();
clear();
show_help();
- standout("Hit any key to continue: ");
- fflush(stdout);
- while (1) {
- len = read(STDIN_FILENO, &ch, 1);
- if (len == -1 && errno == EINTR)
- continue;
- if (len == 0)
- exit(1);
- break;
- }
+ anykey();
+ clear();
break;
case CMD_errors: /* show errors */
if (error_count() == 0) {
new_message(MT_standout,
" Currently no errors to report.");
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
no_command = Yes;
} else {
- reset_display();
clear();
show_errors();
- standout("Hit any key to continue: ");
- fflush(stdout);
- while (1) {
- len = read(STDIN_FILENO, &ch, 1);
- if (len == -1 && errno == EINTR)
- continue;
- if (len == 0)
- exit(1);
- break;
- }
+ anykey();
+ clear();
}
break;
@@ -711,15 +665,13 @@ rundisplay(void)
" This terminal can only "
"display %d processes.",
max_topn);
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
}
if (newval == 0)
display_header(No);
else if (newval > topn && topn == 0) {
/* redraw the header */
display_header(Yes);
- d_header = i_header;
}
topn = newval;
}
@@ -737,8 +689,7 @@ rundisplay(void)
} else {
new_message(MT_standout,
"Delay should be a non-negative number");
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
no_command = Yes;
}
@@ -764,8 +715,7 @@ rundisplay(void)
if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) {
if ((errmsg = kill_procs(tempbuf2)) != NULL) {
new_message(MT_standout, "%s", errmsg);
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
no_command = Yes;
}
} else
@@ -777,8 +727,7 @@ rundisplay(void)
if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) {
if ((errmsg = renice_procs(tempbuf2)) != NULL) {
new_message(MT_standout, "%s", errmsg);
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
no_command = Yes;
}
} else
@@ -791,8 +740,7 @@ rundisplay(void)
new_message(MT_standout | MT_delayed,
" %sisplaying idle processes.",
ps.idle ? "D" : "Not d");
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
break;
case CMD_user:
@@ -808,8 +756,7 @@ rundisplay(void)
no_command = Yes;
} else
ps.uid = uid;
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
} else
clear_message();
break;
@@ -835,8 +782,7 @@ rundisplay(void)
no_command = Yes;
} else
order_index = i;
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
} else
clear_message();
break;
@@ -866,8 +812,7 @@ rundisplay(void)
ps.system = Yes;
}
}
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
} else
clear_message();
break;
@@ -894,8 +839,32 @@ rundisplay(void)
ps.command = NULL;
else
ps.command = strdup(tempbuf2);
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
+ } else
+ clear_message();
+ break;
+
+ case CMD_hl:
+ new_message(MT_standout, "Process ID to higlight: ");
+ if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) {
+ if (tempbuf2[0] == '+' &&
+ tempbuf2[1] == '\0') {
+ hlpid = -1;
+ } else {
+ unsigned long long num;
+ const char *errstr;
+
+ num = strtonum(tempbuf2, 0, INT_MAX,
+ &errstr);
+ if (errstr != NULL || !find_pid(num)) {
+ new_message(MT_standout,
+ " %s: unknown pid",
+ tempbuf2);
+ no_command = Yes;
+ } else
+ hlpid = (pid_t)num;
+ }
+ putr();
} else
clear_message();
break;
@@ -905,12 +874,12 @@ rundisplay(void)
ps.pid = (pid_t)-1; /* pid */
ps.system = old_system;
ps.command = NULL; /* grep */
+ hlpid = -1;
break;
default:
new_message(MT_standout, " BAD CASE IN SWITCH!");
- if (putchar('\r') == EOF)
- exit(1);
+ putr();
}
}
@@ -927,13 +896,10 @@ rundisplay(void)
static void
reset_display(void)
{
- d_loadave = i_loadave;
- d_procstates = i_procstates;
- d_cpustates = i_cpustates;
- d_memory = i_memory;
- d_message = i_message;
- d_header = i_header;
- d_process = i_process;
+ if (smart_terminal) {
+ clear();
+ refresh();
+ }
}
/* ARGSUSED */
@@ -952,7 +918,7 @@ tstop(int signo)
/* ARGSUSED */
void
-winch(int signo)
+sigwinch(int signo)
{
winchflag = 1;
}
diff --git a/usr.bin/top/top.h b/usr.bin/top/top.h
index 6c601039f99..4abc4661189 100644
--- a/usr.bin/top/top.h
+++ b/usr.bin/top/top.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: top.h,v 1.9 2007/03/30 19:21:19 otto Exp $ */
+/* $OpenBSD: top.h,v 1.10 2007/05/29 00:56:56 otto Exp $ */
/*
* Top users/processes display for Unix
@@ -61,13 +61,16 @@ extern int Header_lines;
#define NUM_AVERAGES 3
-/* externs */
-extern const char copyright[];
-extern int overstrike;
+struct errs { /* structure for a system-call error */
+ int err; /* value of errno (that is, the actual error) */
+ char *arg; /* argument that caused the error */
+};
+
+extern struct errs errs[];
+extern int errcnt;
/* commands.c */
-extern void show_help(void);
extern int error_count(void);
extern void show_errors(void);
extern char *kill_procs(char *);