Hey, during writing on icb (client) I discoverd a bug by sending /topic w/o an argument to the daemon, which leads to a segfault.
The segfault of one process leads to a endless loop of the dns which allways returns to the 'dns read'. Attached a diff which solved the problems for me. Greetz kmerz
Index: usr.bin/top/display.c =================================================================== RCS file: /cvs/src/usr.bin/top/display.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 display.c --- usr.bin/top/display.c 26 Aug 2008 14:43:21 -0000 1.1.1.1 +++ usr.bin/top/display.c 18 Dec 2009 20:47:13 -0000 @@ -86,12 +86,8 @@ static char **procstate_names; static char **cpustate_names; static char **memory_names; -static int num_procstates; static int num_cpustates; -static int *lprocstates; -static int64_t **lcpustates; - static int *cpustate_columns; static int cpustate_total_length; @@ -102,6 +98,7 @@ int y_header; int y_idlecursor; int y_procs; extern int ncpu; +extern int combine_cpus; int Header_lines; int header_status = Yes; @@ -127,12 +124,18 @@ int display_resize(void) { int display_lines; + int cpu_lines = (combine_cpus ? 1 : ncpu); + + y_mem = 2 + cpu_lines; + y_header = 4 + cpu_lines; + y_procs = 5 + cpu_lines; + Header_lines = 5 + cpu_lines; /* calculate the current dimensions */ /* if operating in "dumb" mode, we only need one line */ display_lines = smart_terminal ? screen_length - Header_lines : 1; - y_idlecursor = y_message = 3 + ncpu; + y_idlecursor = y_message = 3 + (combine_cpus ? 1 : ncpu); if (screen_length <= y_message) y_idlecursor = y_message = screen_length - 1; @@ -153,7 +156,7 @@ display_resize(void) int display_init(struct statics * statics) { - int display_lines, *ip, i, cpu; + int display_lines, *ip, i; char **pp; if (smart_terminal) { @@ -168,32 +171,15 @@ display_init(struct statics * statics) standendp = empty; } - y_mem = 2 + ncpu; - y_header = 4 + ncpu; - y_procs = 5 + ncpu; - Header_lines = 5 + ncpu; - /* call resize to do the dirty work */ display_lines = display_resize(); /* only do the rest if we need to */ /* save pointers and allocate space for names */ procstate_names = statics->procstate_names; - num_procstates = string_count(procstate_names); - lprocstates = calloc(num_procstates, sizeof(int)); - if (lprocstates == NULL) - err(1, NULL); cpustate_names = statics->cpustate_names; num_cpustates = string_count(cpustate_names); - lcpustates = calloc(ncpu, sizeof(int64_t *)); - if (lcpustates == NULL) - err(1, NULL); - for (cpu = 0; cpu < ncpu; cpu++) { - lcpustates[cpu] = calloc(num_cpustates, sizeof(int64_t)); - if (lcpustates[cpu] == NULL) - err(1, NULL); - } cpustate_columns = calloc(num_cpustates, sizeof(int)); if (cpustate_columns == NULL) @@ -353,20 +339,65 @@ cpustates_tag(int cpu) } return (tag); } else - return ('\0'); + return ("\0"); } void i_cpustates(int64_t *ostates) { - int i, cpu, value; + int i, first, cpu; + double value; int64_t *states; - char **names = cpustate_names, *thisname; + char **names, *thisname; + + if (combine_cpus) { + static double *values; + if (!values) { + values = calloc(num_cpustates, sizeof(*values)); + if (!values) + err(1, NULL); + } + memset(values, 0, num_cpustates * sizeof(*values)); + for (cpu = 0; cpu < ncpu; cpu++) { + names = cpustate_names; + states = ostates + (CPUSTATES * cpu); + i = 0; + while ((thisname = *names++) != NULL) { + if (*thisname != '\0') { + /* retrieve the value and remember it */ + values[i++] += *states++; + } + } + } + if (screen_length > 2 || !smart_terminal) { + names = cpustate_names; + i = 0; + first = 0; + move(2, 0); + clrtoeol(); + addstrp("All CPUs: "); + while ((thisname = *names++) != NULL) { + if (*thisname != '\0') { + value = values[i++] / ncpu; + /* if percentage is >= 1000, + * print it as 100% + */ + printwp((value >= 1000 ? + "%s%4.0f%% %s" : + "%s%4.1f%% %s"), + first++ == 0 ? "" : ", ", + value / 10., thisname); + } + } + putn(); + } + return; + } for (cpu = 0; cpu < ncpu; cpu++) { /* now walk thru the names and print the line */ names = cpustate_names; - i = 0; + first = 0; states = ostates + (CPUSTATES * cpu); if (screen_length > 2 + cpu || !smart_terminal) { @@ -379,10 +410,14 @@ i_cpustates(int64_t *ostates) /* retrieve the value and remember it */ value = *states++; - /* if percentage is >= 1000, print it as 100% */ - printwp((value >= 1000 ? "%s%4.0f%% %s" : - "%s%4.1f%% %s"), i++ == 0 ? "" : ", ", - ((float) value) / 10., thisname); + /* if percentage is >= 1000, + * print it as 100% + */ + printwp((value >= 1000 ? + "%s%4.0f%% %s" : + "%s%4.1f%% %s"), + first++ == 0 ? "" : ", ", + value / 10., thisname); } } putn(); Index: usr.bin/top/machine.c =================================================================== RCS file: /cvs/src/usr.bin/top/machine.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 machine.c --- usr.bin/top/machine.c 26 Aug 2008 14:43:21 -0000 1.1.1.1 +++ usr.bin/top/machine.c 18 Dec 2009 20:47:13 -0000 @@ -68,13 +68,13 @@ struct handle { * These definitions control the format of the per-process area */ static char header[] = - " PID X PRI NICE SIZE RES STATE WAIT TIME CPU COMMAND"; + " PID X PRI NICE SIZE RES STATE WAIT TIME CPU COMMAND"; /* 0123456 -- field to fill in starts at header+6 */ #define UNAME_START 6 #define Proc_format \ - "%5d %-8.8s %3d %4d %5s %5s %-8s %-7.7s %6s %5.2f%% %s" + "%5d %-8.8s %3d %4d %5s %5s %-9s %-7.7s %6s %5.2f%% %s" /* process state names for the "STATE" column of the display */ /* Index: usr.bin/top/screen.c =================================================================== RCS file: /cvs/src/usr.bin/top/screen.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 screen.c --- usr.bin/top/screen.c 26 Aug 2008 14:43:21 -0000 1.1.1.1 +++ usr.bin/top/screen.c 18 Dec 2009 20:47:13 -0000 @@ -213,15 +213,3 @@ go_home(void) refresh(); } } - -/* This has to be defined as a subroutine for tputs (instead of a macro) */ -int -putstdout(int ch) -{ - int ret; - - ret = putchar(ch); - if (ret == EOF) - exit(1); - return (ret); -} Index: usr.bin/top/screen.h =================================================================== RCS file: /cvs/src/usr.bin/top/screen.h,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 screen.h --- usr.bin/top/screen.h 26 Aug 2008 14:43:21 -0000 1.1.1.1 +++ usr.bin/top/screen.h 18 Dec 2009 20:47:13 -0000 @@ -52,4 +52,3 @@ extern void end_screen(void); extern void reinit_screen(void); extern void get_screensize(void); extern void go_home(void); -extern int putstdout(int); Index: usr.bin/top/top.1 =================================================================== RCS file: /cvs/src/usr.bin/top/top.1,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 top.1 --- usr.bin/top/top.1 26 Aug 2008 14:43:21 -0000 1.1.1.1 +++ usr.bin/top/top.1 18 Dec 2009 20:47:13 -0000 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd $Mdocdate: August 26 2008 $ +.Dd $Mdocdate: December 10 2009 $ .Dt TOP 1 .Os .Sh NAME @@ -31,7 +31,7 @@ .Sh SYNOPSIS .Nm top .Bk -words -.Op Fl bCIinqSTu +.Op Fl 1bCIinqSTu .Op Fl d Ar count .Op Fl g Ar string .Op Fl o Ar field @@ -73,6 +73,8 @@ terminal. .Pp The options are as follows: .Bl -tag -width Ds +.It Fl 1 +Display CPU statistics on a single line instead of a line per CPU. .It Fl b Use .Em batch Index: usr.bin/top/top.c =================================================================== RCS file: /cvs/src/usr.bin/top/top.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 top.c --- usr.bin/top/top.c 26 Aug 2008 14:43:21 -0000 1.1.1.1 +++ usr.bin/top/top.c 18 Dec 2009 20:47:14 -0000 @@ -82,6 +82,7 @@ int old_system = No; int old_threads = No; int show_args = No; pid_t hlpid = -1; +int combine_cpus = 0; #if Default_TOPN == Infinity char topn_specified = No; @@ -115,6 +116,7 @@ char topn_specified = No; #define CMD_grep 20 #define CMD_add 21 #define CMD_hl 22 +#define CMD_cpus 23 static void usage(void) @@ -122,7 +124,7 @@ usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-bCIinqSTu] [-d count] [-g string] [-o field] " + "usage: %s [-1bCIinqSTu] [-d count] [-g string] [-o field] " "[-p pid] [-s time]\n\t[-U user] [number]\n", __progname); } @@ -133,12 +135,14 @@ parseargs(int ac, char **av) char *endp; int i; - while ((i = getopt(ac, av, "STICbinqus:d:p:U:o:g:")) != -1) { + while ((i = getopt(ac, av, "1STICbinqus:d:p:U:o:g:")) != -1) { switch (i) { + case '1': + combine_cpus = 1; + break; case 'C': show_args = Yes; break; - case 'u': /* toggle uid/username display */ do_unames = !do_unames; break; @@ -164,8 +168,8 @@ parseargs(int ac, char **av) } case 'S': /* show system processes */ - ps.system = Yes; - old_system = Yes; + ps.system = !ps.system; + old_system = !old_system; break; case 'T': /* show threads */ @@ -189,6 +193,8 @@ parseargs(int ac, char **av) case 'd': /* number of displays to show */ if ((i = atoiwi(optarg)) != Invalid && i != 0) { displays = i; + if (displays == 1) + interactive = No; break; } new_message(MT_delayed, @@ -513,7 +519,7 @@ rundisplay(void) int change, i; struct pollfd pfd[1]; uid_t uid; - static char command_chars[] = "\f qh?en#sdkriIuSopCTg+P"; + static char command_chars[] = "\f qh?en#sdkriIuSopCTg+P1"; /* * assume valid command unless told @@ -896,7 +902,11 @@ rundisplay(void) ps.command = NULL; /* grep */ hlpid = -1; break; - + case CMD_cpus: + combine_cpus = !combine_cpus; + max_topn = display_resize(); + reset_display(); + break; default: new_message(MT_standout, " BAD CASE IN SWITCH!"); putr(); Index: usr.bin/top/username.c =================================================================== RCS file: /cvs/src/usr.bin/top/username.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 username.c --- usr.bin/top/username.c 26 Aug 2008 14:43:22 -0000 1.1.1.1 +++ usr.bin/top/username.c 18 Dec 2009 20:47:14 -0000 @@ -60,7 +60,7 @@ struct hash_el { char name[_PW_NAME_LEN + 1]; }; -static int enter_user(uid_t, char *, int); +static int enter_user(uid_t, char *); static int get_user(uid_t); #define is_empty_hash(x) (hash_table[x].name[0] == 0) @@ -98,29 +98,24 @@ userid(char *username) return ((uid_t)-1); /* enter the result in the hash table */ - enter_user(pwd->pw_uid, username, 1); + enter_user(pwd->pw_uid, username); /* return our result */ return (pwd->pw_uid); } -/* - * wecare: 1 = enter it always, 0 = nice to have - */ static int -enter_user(uid_t uid, char *name, int wecare) +enter_user(uid_t uid, char *name) { int hashindex; #ifdef DEBUG - fprintf(stderr, "enter_hash(%u, %s, %d)\n", uid, name, wecare); + fprintf(stderr, "enter_hash(%u, %s)\n", uid, name); #endif hashindex = hashit(uid); if (!is_empty_hash(hashindex)) { - if (!wecare) - return 0; /* Don't clobber a slot for trash */ if (hash_table[hashindex].uid == uid) return (hashindex); /* Fortuitous find */ } @@ -141,8 +136,8 @@ get_user(uid_t uid) /* no performance penalty for using getpwuid makes it easy */ if ((pwd = getpwuid(uid)) != NULL) - return (enter_user(pwd->pw_uid, pwd->pw_name, 1)); + return (enter_user(pwd->pw_uid, pwd->pw_name)); /* if we can't find the name at all, then use the uid as the name */ - return (enter_user(uid, format_uid(uid), 1)); + return (enter_user(uid, format_uid(uid))); }