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