diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/top/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/top/commands.c | 72 | ||||
-rw-r--r-- | usr.bin/top/display.c | 684 | ||||
-rw-r--r-- | usr.bin/top/display.h | 53 | ||||
-rw-r--r-- | usr.bin/top/machine.c | 5 | ||||
-rw-r--r-- | usr.bin/top/machine.h | 4 | ||||
-rw-r--r-- | usr.bin/top/screen.c | 120 | ||||
-rw-r--r-- | usr.bin/top/screen.h | 12 | ||||
-rw-r--r-- | usr.bin/top/top.1 | 7 | ||||
-rw-r--r-- | usr.bin/top/top.c | 182 | ||||
-rw-r--r-- | usr.bin/top/top.h | 13 |
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, ¤t[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 *); |