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

Reply via email to