From 00528822004e5763c669e58191f10c5202f679b5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 11 Sep 2009 23:26:42 +0200 Subject: top: add -m ("memory") option Signed-off-by: Denys Vlasenko --- TODO | 23 ++++++++++++ include/usage.h | 2 +- libbb/getopt32.c | 14 ++++---- procps/top.c | 108 +++++++++++++++++++++++++++++-------------------------- 4 files changed, 88 insertions(+), 59 deletions(-) diff --git a/TODO b/TODO index cd2aa0e87..136aeb7b8 100644 --- a/TODO +++ b/TODO @@ -320,6 +320,29 @@ vdprintf() -> similar sized functionality Unicode work needed: +Unicode support uses libc multibyte functions if LOCALE_SUPPORT is on +(in this case, the code will also support many more encodings), +or uses a limited subset of re-implemented multibyte functions +which only understand "one byte == one char" and unicode. +This is useful if you build against uclibc with locale support disabled. + +Unicode-dependent applets must call check_unicode_in_env() when they +begin executing. + +Applet code may conditionalize on FEATURE_ASSUME_UNICODE +in order to use more efficient code if unicode support is not requested. + +Available functions (if you need more, implement them in libbb/unicode.c +so that they work without LOCALE_SUPPORT too): + +int bb_mbstrlen(str) - multibyte-aware strlen +size_t mbstowcs(wdest, src, n) +size_t wcstombs(dest, wsrc, n) +size_t wcrtomb(str, wc, wstate) +int iswspace(wc) +int iswalnum(wc) +int iswpunct(wc) + Applets which only need to align columns on screen correctly: ls - already done, use source as an example diff --git a/include/usage.h b/include/usage.h index 036cf9db7..907eb78f4 100644 --- a/include/usage.h +++ b/include/usage.h @@ -4566,7 +4566,7 @@ "Defaults: SECS: 10, SIG: TERM." \ #define top_trivial_usage \ - "[-b] [-nCOUNT] [-dSECONDS]" + "[-b] [-nCOUNT] [-dSECONDS]" IF_FEATURE_TOPMEM(" [-m]") #define top_full_usage "\n\n" \ "Provide a view of process activity in real time.\n" \ "Read the status of all processes from /proc each SECONDS\n" \ diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 17b8dd1a4..cab3eb745 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c @@ -147,15 +147,15 @@ const char *opt_complementary Special characters: - "-" A dash as the first char in a opt_complementary group forces - all arguments to be treated as options, even if they have - no leading dashes. Next char in this case can't be a digit (0-9), - use ':' or end of line. For example: + "-" A group consisting of just a dash forces all arguments + to be treated as options, even if they have no leading dashes. + Next char in this case can't be a digit (0-9), use ':' or end of line. + Example: - opt_complementary = "-:w-x:x-w"; - getopt32(argv, "wx"); + opt_complementary = "-:w-x:x-w"; // "-w-x:x-w" would also work, + getopt32(argv, "wx"); // but is less readable - Allows any arguments to be given without a dash (./program w x) + This makes it possible to use options without a dash (./program w x) as well as with a dash (./program -x). NB: getopt32() will leak a small amount of memory if you use diff --git a/procps/top.c b/procps/top.c index 62b9c1e1b..92360a005 100644 --- a/procps/top.c +++ b/procps/top.c @@ -131,7 +131,8 @@ enum { OPT_d = (1 << 0), OPT_n = (1 << 1), OPT_b = (1 << 2), - OPT_EOF = (1 << 3), /* pseudo: "we saw EOF in stdin" */ + OPT_m = (1 << 3), + OPT_EOF = (1 << 4), /* pseudo: "we saw EOF in stdin" */ }; #define OPT_BATCH_MODE (option_mask32 & OPT_b) @@ -348,29 +349,29 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) jiffy_counts_t *p_jif, *p_prev_jif; int i; -#if ENABLE_FEATURE_TOP_SMP_CPU +# if ENABLE_FEATURE_TOP_SMP_CPU int n_cpu_lines; -#endif +# endif /* using (unsigned) casts to make operations cheaper */ -#define CALC_TOT_DIFF ((unsigned)(p_jif->total - p_prev_jif->total) ? : 1) - -#if ENABLE_FEATURE_TOP_DECIMALS -#define CALC_STAT(xxx) char xxx[8] -#define SHOW_STAT(xxx) fmt_100percent_8(xxx, (unsigned)(p_jif->xxx - p_prev_jif->xxx), total_diff) -#define FMT "%s" -#else -#define CALC_STAT(xxx) unsigned xxx = 100 * (unsigned)(p_jif->xxx - p_prev_jif->xxx) / total_diff -#define SHOW_STAT(xxx) xxx -#define FMT "%4u%% " -#endif - -#if !ENABLE_FEATURE_TOP_SMP_CPU +# define CALC_TOT_DIFF ((unsigned)(p_jif->total - p_prev_jif->total) ? : 1) + +# if ENABLE_FEATURE_TOP_DECIMALS +# define CALC_STAT(xxx) char xxx[8] +# define SHOW_STAT(xxx) fmt_100percent_8(xxx, (unsigned)(p_jif->xxx - p_prev_jif->xxx), total_diff) +# define FMT "%s" +# else +# define CALC_STAT(xxx) unsigned xxx = 100 * (unsigned)(p_jif->xxx - p_prev_jif->xxx) / total_diff +# define SHOW_STAT(xxx) xxx +# define FMT "%4u%% " +# endif + +# if !ENABLE_FEATURE_TOP_SMP_CPU { i = 1; p_jif = &cur_jif; p_prev_jif = &prev_jif; -#else +# else /* Loop thru CPU(s) */ n_cpu_lines = smp_cpu_info ? num_cpus : 1; if (n_cpu_lines > *lines_rem_p) @@ -379,7 +380,7 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) for (i = 0; i < n_cpu_lines; i++) { p_jif = &cpu_jif[i]; p_prev_jif = &cpu_prev_jif[i]; -#endif +# endif total_diff = CALC_TOT_DIFF; { /* Need a block: CALC_STAT are declarations */ @@ -394,12 +395,12 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) snprintf(scrbuf, scr_width, /* Barely fits in 79 chars when in "decimals" mode. */ -#if ENABLE_FEATURE_TOP_SMP_CPU +# if ENABLE_FEATURE_TOP_SMP_CPU "CPU%s:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", (smp_cpu_info ? utoa(i) : ""), -#else +# else "CPU:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", -#endif +# endif SHOW_STAT(usr), SHOW_STAT(sys), SHOW_STAT(nic), SHOW_STAT(idle), SHOW_STAT(iowait), SHOW_STAT(irq), SHOW_STAT(softirq) /*, SHOW_STAT(steal) - what is this 'steal' thing? */ @@ -408,13 +409,13 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) puts(scrbuf); } } -#undef SHOW_STAT -#undef CALC_STAT -#undef FMT +# undef SHOW_STAT +# undef CALC_STAT +# undef FMT *lines_rem_p -= i; } #else /* !ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS */ -#define display_cpus(scr_width, scrbuf, lines_rem) ((void)0) +# define display_cpus(scr_width, scrbuf, lines_rem) ((void)0) #endif static unsigned long display_header(int scr_width, int *lines_rem_p) @@ -528,15 +529,15 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width) lines_rem--; #if ENABLE_FEATURE_TOP_DECIMALS -#define UPSCALE 1000 -#define CALC_STAT(name, val) div_t name = div((val), 10) -#define SHOW_STAT(name) name.quot, '0'+name.rem -#define FMT "%3u.%c" +# define UPSCALE 1000 +# define CALC_STAT(name, val) div_t name = div((val), 10) +# define SHOW_STAT(name) name.quot, '0'+name.rem +# define FMT "%3u.%c" #else -#define UPSCALE 100 -#define CALC_STAT(name, val) unsigned name = (val) -#define SHOW_STAT(name) name -#define FMT "%4u%%" +# define UPSCALE 100 +# define CALC_STAT(name, val) unsigned name = (val) +# define SHOW_STAT(name) name +# define FMT "%4u%%" #endif /* * MEM% = s->vsz/MemTotal @@ -646,9 +647,9 @@ static void reset_term(void) tcsetattr_stdin_TCSANOW(&initial_settings); if (ENABLE_FEATURE_CLEAN_UP) { clearmems(); -#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE +# if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE free(prev_hist); -#endif +# endif } } @@ -895,7 +896,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) pfd[0].fd = 0; pfd[0].events = POLLIN; -#endif /* FEATURE_USE_TERMIOS */ +#endif INIT_G(); @@ -909,10 +910,15 @@ int top_main(int argc UNUSED_PARAM, char **argv) #endif /* all args are options; -n NUM */ - opt_complementary = "-"; - col = getopt32(argv, "d:n:b", &str_interval, &str_iterations); + opt_complementary = "-"; /* options can be specified w/o dash */ + col = getopt32(argv, "d:n:b"IF_FEATURE_TOPMEM("m"), &str_interval, &str_iterations); +#if ENABLE_FEATURE_TOPMEM + if (col & OPT_m) /* -m (busybox specific) */ + scan_mask = TOPMEM_MASK; +#endif if (col & OPT_d) { - /* work around for "-d 1" -> "-d -1" done by getopt32 */ + /* work around for "-d 1" -> "-d -1" done by getopt32 + * (opt_complementary == "-" does this) */ if (str_interval[0] == '-') str_interval++; /* Need to limit it to not overflow poll timeout */ @@ -934,7 +940,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) bb_signals(BB_FATAL_SIGS, sig_catcher); tcsetattr_stdin_TCSANOW(&new_settings); -#endif /* FEATURE_USE_TERMIOS */ +#endif #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE sort_function[0] = pcpu_sort; @@ -942,7 +948,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) sort_function[2] = time_sort; #else sort_function[0] = mem_sort; -#endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */ +#endif while (1) { procps_status_t *p = NULL; @@ -956,7 +962,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) sleep(interval); continue; } -#endif /* FEATURE_USE_TERMIOS */ +#endif if (col > LINE_BUF_SIZE-2) /* +2 bytes for '\n', NUL, */ col = LINE_BUF_SIZE-2; @@ -1015,7 +1021,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) qsort(top, ntop, sizeof(top_status_t), (void*)mult_lvl_cmp); #else qsort(top, ntop, sizeof(top_status_t), (void*)(sort_function[0])); -#endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */ +#endif } #if ENABLE_FEATURE_TOPMEM else { /* TOPMEM */ @@ -1058,12 +1064,12 @@ int top_main(int argc UNUSED_PARAM, char **argv) if (c == 'm') { IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) sort_function[0] = mem_sort; -#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE +# if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE sort_function[1] = pcpu_sort; sort_function[2] = time_sort; -#endif +# endif } -#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE +# if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE if (c == 'p') { IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) sort_function[0] = pcpu_sort; @@ -1076,7 +1082,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) sort_function[1] = mem_sort; sort_function[2] = pcpu_sort; } -#if ENABLE_FEATURE_TOPMEM +# if ENABLE_FEATURE_TOPMEM if (c == 's') { scan_mask = TOPMEM_MASK; free(prev_hist); @@ -1086,8 +1092,8 @@ int top_main(int argc UNUSED_PARAM, char **argv) } if (c == 'r') inverted ^= 1; -#endif -#if ENABLE_FEATURE_TOP_SMP_CPU +# endif +# if ENABLE_FEATURE_TOP_SMP_CPU /* procps-2.0.18 uses 'C', 3.2.7 uses '1' */ if (c == 'c' || c == '1') { /* User wants to toggle per cpu <> aggregate */ @@ -1104,8 +1110,8 @@ int top_main(int argc UNUSED_PARAM, char **argv) smp_cpu_info = !smp_cpu_info; get_jiffy_counts(); } -#endif -#endif +# endif +# endif } #endif /* FEATURE_USE_TERMIOS */ } /* end of "while (1)" */ -- cgit v1.2.3