diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2007-10-16 07:33:09 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2007-10-16 07:33:09 +0000 |
commit | e705732a6622d536ead13ca626589e130949e712 (patch) | |
tree | ffcad1f8a2ea9d4b86b61d45e00df23c9463ffc6 | |
parent | 34c77c62d876eae153056388e21c73a29964c400 (diff) |
Properly adjust headers displayed when the screen contains few lines.
Avoid a segv also. Problem reported by Mark Lumsden; inital diff by
me, further polishing by Mark. Tested by ray@ canacar@ hshoexer@
-rw-r--r-- | usr.bin/top/display.c | 287 | ||||
-rw-r--r-- | usr.bin/top/top.c | 8 |
2 files changed, 155 insertions, 140 deletions
diff --git a/usr.bin/top/display.c b/usr.bin/top/display.c index d56c73df4ab..26ce1401d44 100644 --- a/usr.bin/top/display.c +++ b/usr.bin/top/display.c @@ -1,4 +1,4 @@ -/* $OpenBSD: display.c,v 1.29 2007/09/30 13:26:39 otto Exp $ */ +/* $OpenBSD: display.c,v 1.30 2007/10/16 07:33:08 otto Exp $ */ /* * Top users/processes display for Unix @@ -135,6 +135,10 @@ display_resize(void) /* 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; + if (screen_length <= y_message) + y_idlecursor = y_message = screen_length - 1; + /* * we don't want more than MAX_COLS columns, since the * machine-dependent modules make static allocations based on @@ -168,9 +172,7 @@ display_init(struct statics * statics) } y_mem = 2 + ncpu; - y_message = 3 + ncpu; y_header = 4 + ncpu; - y_idlecursor = 3 + ncpu; y_procs = 5 + ncpu; Header_lines = 5 + ncpu; @@ -178,42 +180,44 @@ display_init(struct statics * statics) display_lines = display_resize(); /* only do the rest if we need to */ - if (display_lines > -1) { - /* 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) + /* 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); - 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) + err(1, NULL); + + memory_names = statics->memory_names; + + /* calculate starting columns where needed */ + cpustate_total_length = 0; + pp = cpustate_names; + ip = cpustate_columns; + while (*pp != NULL) { + if ((i = strlen(*pp++)) > 0) { + *ip++ = cpustate_total_length; + cpustate_total_length += i + 8; } - - cpustate_columns = calloc(num_cpustates, sizeof(int)); - if (cpustate_columns == NULL) - err(1, NULL); + } - memory_names = statics->memory_names; + if (display_lines < 0) + display_lines = 0; - /* calculate starting columns where needed */ - cpustate_total_length = 0; - pp = cpustate_names; - ip = cpustate_columns; - while (*pp != NULL) { - if ((i = strlen(*pp++)) > 0) { - *ip++ = cpustate_total_length; - cpustate_total_length += i + 8; - } - } - } /* return number of lines available */ return (display_lines); } @@ -221,19 +225,20 @@ display_init(struct statics * statics) void i_loadave(pid_t mpid, double *avenrun) { - int i; - - move(0, 0); - clrtoeol(); + if (screen_length > 1 || !smart_terminal) { + int i; - /* mpid == -1 implies this system doesn't have an _mpid */ - if (mpid != -1) - printwp("last pid: %5ld; ", (long) mpid); + move(0, 0); + clrtoeol(); - addstrp("load averages"); + addstrp("load averages"); + /* mpid == -1 implies this system doesn't have an _mpid */ + if (mpid != -1) + printwp("last pid: %5ld; ", (long) mpid); - for (i = 0; i < 3; i++) - printwp("%c %5.2f", i == 0 ? ':' : ',', avenrun[i]); + for (i = 0; i < 3; i++) + printwp("%c %5.2f", i == 0 ? ':' : ',', avenrun[i]); + } } /* @@ -250,22 +255,23 @@ i_loadave(pid_t mpid, double *avenrun) void i_timeofday(time_t * tod) { - - if (smart_terminal) { - move(0, screen_width - 8); - } else { - if (fputs(" ", stdout) == EOF) - exit(1); - } + if (screen_length > 1 || !smart_terminal) { + if (smart_terminal) { + move(0, screen_width - 8); + } else { + if (fputs(" ", stdout) == EOF) + exit(1); + } #ifdef DEBUG - { - char *foo; - foo = ctime(tod); - addstrp(foo); - } + { + char *foo; + foo = ctime(tod); + addstrp(foo); + } #endif - printwp("%-8.8s", &(ctime(tod)[11])); - putn(); + printwp("%-8.8s", &(ctime(tod)[11])); + putn(); + } } /* @@ -277,31 +283,33 @@ i_timeofday(time_t * tod) 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 */ - printwp("%d processes:", total); + if (screen_length > 2 || !smart_terminal) { + int i; + char procstates_buffer[MAX_COLS]; - 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); + move(1, 0); + clrtoeol(); + /* write current number of processes and remember the value */ + 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); + /* format and print the process state summary */ + summary_format(procstates_buffer, sizeof(procstates_buffer), brkdn, + procstate_names); - addstrp(procstates_buffer); - putn(); + addstrp(procstates_buffer); + putn(); + } } /* @@ -315,38 +323,41 @@ i_procstates(int total, int *brkdn) static char * cpustates_tag(int cpu) { - static char *tag; - static int cpulen, old_width; - int i; - - if (cpulen == 0 && ncpu > 1) { - /* compute length of the cpu string */ - for (i = ncpu; i > 0; cpulen++, i /= 10) - continue; - } + if (screen_length > 3 || !smart_terminal) { + static char *tag; + static int cpulen, old_width; + int i; + + if (cpulen == 0 && ncpu > 1) { + /* compute length of the cpu string */ + for (i = ncpu; i > 0; cpulen++, i /= 10) + continue; + } - if (old_width == screen_width) { - if (ncpu > 1) { - /* just store the cpu number in the tag */ - i = tag[3 + cpulen]; - snprintf(tag + 3, cpulen + 1, "%.*d", cpulen, cpu); - tag[3 + cpulen] = i; + if (old_width == screen_width) { + if (ncpu > 1) { + /* just store the cpu number in the tag */ + i = tag[3 + cpulen]; + snprintf(tag + 3, cpulen + 1, "%.*d", cpulen, cpu); + tag[3 + cpulen] = i; + } + } else { + /* + * use a long tag if it will fit, otherwise use short one. + */ + free(tag); + if (cpustate_total_length + 10 + cpulen >= screen_width) + i = asprintf(&tag, "CPU%.*d: ", cpulen, cpu); + else + i = asprintf(&tag, "CPU%.*d states: ", cpulen, cpu); + if (i == -1) + tag = NULL; + else + old_width = screen_width; } - } else { - /* - * use a long tag if it will fit, otherwise use short one. - */ - free(tag); - if (cpustate_total_length + 10 + cpulen >= screen_width) - i = asprintf(&tag, "CPU%.*d: ", cpulen, cpu); - else - i = asprintf(&tag, "CPU%.*d states: ", cpulen, cpu); - if (i == -1) - tag = NULL; - else - old_width = screen_width; - } - return (tag); + return (tag); + } else + return ('\0'); } void @@ -357,27 +368,30 @@ 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 */ - addstrp(cpustates_tag(cpu)); - /* now walk thru the names and print the line */ names = cpustate_names; i = 0; states = ostates + (CPUSTATES * cpu); - while ((thisname = *names++) != NULL) { - if (*thisname != '\0') { - /* 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 (screen_length > 2 + cpu || !smart_terminal) { + move(2 + cpu, 0); + clrtoeol(); + /* print tag and bump lastline */ + addstrp(cpustates_tag(cpu)); + + while ((thisname = *names++) != NULL) { + if (*thisname != '\0') { + /* 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); + } } + putn(); } - putn(); } } @@ -390,17 +404,19 @@ i_cpustates(int64_t *ostates) void i_memory(int *stats) { - char memory_buffer[MAX_COLS]; + if (screen_length > y_mem || !smart_terminal) { + char memory_buffer[MAX_COLS]; - move(y_mem, 0); - clrtoeol(); - addstrp("Memory: "); + move(y_mem, 0); + clrtoeol(); + addstrp("Memory: "); - /* format and print the memory summary */ - summary_format(memory_buffer, sizeof(memory_buffer), stats, - memory_names); - addstrp(memory_buffer); - putn(); + /* format and print the memory summary */ + summary_format(memory_buffer, sizeof(memory_buffer), stats, + memory_names); + addstrp(memory_buffer); + putn(); + } } /* @@ -460,7 +476,8 @@ void i_header(char *text) { header_length = strlen(text); - if (header_status == ON) { + if (header_status == ON && (screen_length > y_header + || !smart_terminal)) { if (!smart_terminal) { putn(); if (fputs(text, stdout) == EOF) diff --git a/usr.bin/top/top.c b/usr.bin/top/top.c index 26181c20503..a7dde5aa677 100644 --- a/usr.bin/top/top.c +++ b/usr.bin/top/top.c @@ -1,4 +1,4 @@ -/* $OpenBSD: top.c,v 1.57 2007/10/04 07:47:53 otto Exp $ */ +/* $OpenBSD: top.c,v 1.58 2007/10/16 07:33:08 otto Exp $ */ /* * Top users/processes display for Unix @@ -337,10 +337,8 @@ main(int argc, char *argv[]) header_text = format_header(uname_field); /* initialize display interface */ - if ((max_topn = display_init(&statics)) == -1) { - warnx("can't allocate sufficient memory"); - exit(4); - } + max_topn = display_init(&statics); + /* print warning if user requested more processes than we can display */ if (topn > max_topn) { warnx("warning: this terminal can only display %d processes", |