diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-09-11 23:26:42 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-09-11 23:26:42 +0200 |
commit | 00528822004e5763c669e58191f10c5202f679b5 (patch) | |
tree | c60a30ca27a190bb09f6d4fe3948c56e0aef3583 | |
parent | 56573cb4f7393fdb320660a5c258c72688a74f64 (diff) | |
download | busybox-w32-00528822004e5763c669e58191f10c5202f679b5.tar.gz busybox-w32-00528822004e5763c669e58191f10c5202f679b5.tar.bz2 busybox-w32-00528822004e5763c669e58191f10c5202f679b5.zip |
top: add -m ("memory") option
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | TODO | 23 | ||||
-rw-r--r-- | include/usage.h | 2 | ||||
-rw-r--r-- | libbb/getopt32.c | 14 | ||||
-rw-r--r-- | procps/top.c | 108 |
4 files changed, 88 insertions, 59 deletions
@@ -320,6 +320,29 @@ vdprintf() -> similar sized functionality | |||
320 | 320 | ||
321 | Unicode work needed: | 321 | Unicode work needed: |
322 | 322 | ||
323 | Unicode support uses libc multibyte functions if LOCALE_SUPPORT is on | ||
324 | (in this case, the code will also support many more encodings), | ||
325 | or uses a limited subset of re-implemented multibyte functions | ||
326 | which only understand "one byte == one char" and unicode. | ||
327 | This is useful if you build against uclibc with locale support disabled. | ||
328 | |||
329 | Unicode-dependent applets must call check_unicode_in_env() when they | ||
330 | begin executing. | ||
331 | |||
332 | Applet code may conditionalize on FEATURE_ASSUME_UNICODE | ||
333 | in order to use more efficient code if unicode support is not requested. | ||
334 | |||
335 | Available functions (if you need more, implement them in libbb/unicode.c | ||
336 | so that they work without LOCALE_SUPPORT too): | ||
337 | |||
338 | int bb_mbstrlen(str) - multibyte-aware strlen | ||
339 | size_t mbstowcs(wdest, src, n) | ||
340 | size_t wcstombs(dest, wsrc, n) | ||
341 | size_t wcrtomb(str, wc, wstate) | ||
342 | int iswspace(wc) | ||
343 | int iswalnum(wc) | ||
344 | int iswpunct(wc) | ||
345 | |||
323 | Applets which only need to align columns on screen correctly: | 346 | Applets which only need to align columns on screen correctly: |
324 | 347 | ||
325 | ls - already done, use source as an example | 348 | 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 @@ | |||
4566 | "Defaults: SECS: 10, SIG: TERM." \ | 4566 | "Defaults: SECS: 10, SIG: TERM." \ |
4567 | 4567 | ||
4568 | #define top_trivial_usage \ | 4568 | #define top_trivial_usage \ |
4569 | "[-b] [-nCOUNT] [-dSECONDS]" | 4569 | "[-b] [-nCOUNT] [-dSECONDS]" IF_FEATURE_TOPMEM(" [-m]") |
4570 | #define top_full_usage "\n\n" \ | 4570 | #define top_full_usage "\n\n" \ |
4571 | "Provide a view of process activity in real time.\n" \ | 4571 | "Provide a view of process activity in real time.\n" \ |
4572 | "Read the status of all processes from /proc each SECONDS\n" \ | 4572 | "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 | |||
147 | 147 | ||
148 | Special characters: | 148 | Special characters: |
149 | 149 | ||
150 | "-" A dash as the first char in a opt_complementary group forces | 150 | "-" A group consisting of just a dash forces all arguments |
151 | all arguments to be treated as options, even if they have | 151 | to be treated as options, even if they have no leading dashes. |
152 | no leading dashes. Next char in this case can't be a digit (0-9), | 152 | Next char in this case can't be a digit (0-9), use ':' or end of line. |
153 | use ':' or end of line. For example: | 153 | Example: |
154 | 154 | ||
155 | opt_complementary = "-:w-x:x-w"; | 155 | opt_complementary = "-:w-x:x-w"; // "-w-x:x-w" would also work, |
156 | getopt32(argv, "wx"); | 156 | getopt32(argv, "wx"); // but is less readable |
157 | 157 | ||
158 | Allows any arguments to be given without a dash (./program w x) | 158 | This makes it possible to use options without a dash (./program w x) |
159 | as well as with a dash (./program -x). | 159 | as well as with a dash (./program -x). |
160 | 160 | ||
161 | NB: getopt32() will leak a small amount of memory if you use | 161 | 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 { | |||
131 | OPT_d = (1 << 0), | 131 | OPT_d = (1 << 0), |
132 | OPT_n = (1 << 1), | 132 | OPT_n = (1 << 1), |
133 | OPT_b = (1 << 2), | 133 | OPT_b = (1 << 2), |
134 | OPT_EOF = (1 << 3), /* pseudo: "we saw EOF in stdin" */ | 134 | OPT_m = (1 << 3), |
135 | OPT_EOF = (1 << 4), /* pseudo: "we saw EOF in stdin" */ | ||
135 | }; | 136 | }; |
136 | #define OPT_BATCH_MODE (option_mask32 & OPT_b) | 137 | #define OPT_BATCH_MODE (option_mask32 & OPT_b) |
137 | 138 | ||
@@ -348,29 +349,29 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) | |||
348 | jiffy_counts_t *p_jif, *p_prev_jif; | 349 | jiffy_counts_t *p_jif, *p_prev_jif; |
349 | int i; | 350 | int i; |
350 | 351 | ||
351 | #if ENABLE_FEATURE_TOP_SMP_CPU | 352 | # if ENABLE_FEATURE_TOP_SMP_CPU |
352 | int n_cpu_lines; | 353 | int n_cpu_lines; |
353 | #endif | 354 | # endif |
354 | 355 | ||
355 | /* using (unsigned) casts to make operations cheaper */ | 356 | /* using (unsigned) casts to make operations cheaper */ |
356 | #define CALC_TOT_DIFF ((unsigned)(p_jif->total - p_prev_jif->total) ? : 1) | 357 | # define CALC_TOT_DIFF ((unsigned)(p_jif->total - p_prev_jif->total) ? : 1) |
357 | 358 | ||
358 | #if ENABLE_FEATURE_TOP_DECIMALS | 359 | # if ENABLE_FEATURE_TOP_DECIMALS |
359 | #define CALC_STAT(xxx) char xxx[8] | 360 | # define CALC_STAT(xxx) char xxx[8] |
360 | #define SHOW_STAT(xxx) fmt_100percent_8(xxx, (unsigned)(p_jif->xxx - p_prev_jif->xxx), total_diff) | 361 | # define SHOW_STAT(xxx) fmt_100percent_8(xxx, (unsigned)(p_jif->xxx - p_prev_jif->xxx), total_diff) |
361 | #define FMT "%s" | 362 | # define FMT "%s" |
362 | #else | 363 | # else |
363 | #define CALC_STAT(xxx) unsigned xxx = 100 * (unsigned)(p_jif->xxx - p_prev_jif->xxx) / total_diff | 364 | # define CALC_STAT(xxx) unsigned xxx = 100 * (unsigned)(p_jif->xxx - p_prev_jif->xxx) / total_diff |
364 | #define SHOW_STAT(xxx) xxx | 365 | # define SHOW_STAT(xxx) xxx |
365 | #define FMT "%4u%% " | 366 | # define FMT "%4u%% " |
366 | #endif | 367 | # endif |
367 | 368 | ||
368 | #if !ENABLE_FEATURE_TOP_SMP_CPU | 369 | # if !ENABLE_FEATURE_TOP_SMP_CPU |
369 | { | 370 | { |
370 | i = 1; | 371 | i = 1; |
371 | p_jif = &cur_jif; | 372 | p_jif = &cur_jif; |
372 | p_prev_jif = &prev_jif; | 373 | p_prev_jif = &prev_jif; |
373 | #else | 374 | # else |
374 | /* Loop thru CPU(s) */ | 375 | /* Loop thru CPU(s) */ |
375 | n_cpu_lines = smp_cpu_info ? num_cpus : 1; | 376 | n_cpu_lines = smp_cpu_info ? num_cpus : 1; |
376 | if (n_cpu_lines > *lines_rem_p) | 377 | if (n_cpu_lines > *lines_rem_p) |
@@ -379,7 +380,7 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) | |||
379 | for (i = 0; i < n_cpu_lines; i++) { | 380 | for (i = 0; i < n_cpu_lines; i++) { |
380 | p_jif = &cpu_jif[i]; | 381 | p_jif = &cpu_jif[i]; |
381 | p_prev_jif = &cpu_prev_jif[i]; | 382 | p_prev_jif = &cpu_prev_jif[i]; |
382 | #endif | 383 | # endif |
383 | total_diff = CALC_TOT_DIFF; | 384 | total_diff = CALC_TOT_DIFF; |
384 | 385 | ||
385 | { /* Need a block: CALC_STAT are declarations */ | 386 | { /* Need a block: CALC_STAT are declarations */ |
@@ -394,12 +395,12 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) | |||
394 | 395 | ||
395 | snprintf(scrbuf, scr_width, | 396 | snprintf(scrbuf, scr_width, |
396 | /* Barely fits in 79 chars when in "decimals" mode. */ | 397 | /* Barely fits in 79 chars when in "decimals" mode. */ |
397 | #if ENABLE_FEATURE_TOP_SMP_CPU | 398 | # if ENABLE_FEATURE_TOP_SMP_CPU |
398 | "CPU%s:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", | 399 | "CPU%s:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", |
399 | (smp_cpu_info ? utoa(i) : ""), | 400 | (smp_cpu_info ? utoa(i) : ""), |
400 | #else | 401 | # else |
401 | "CPU:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", | 402 | "CPU:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", |
402 | #endif | 403 | # endif |
403 | SHOW_STAT(usr), SHOW_STAT(sys), SHOW_STAT(nic), SHOW_STAT(idle), | 404 | SHOW_STAT(usr), SHOW_STAT(sys), SHOW_STAT(nic), SHOW_STAT(idle), |
404 | SHOW_STAT(iowait), SHOW_STAT(irq), SHOW_STAT(softirq) | 405 | SHOW_STAT(iowait), SHOW_STAT(irq), SHOW_STAT(softirq) |
405 | /*, SHOW_STAT(steal) - what is this 'steal' thing? */ | 406 | /*, 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) | |||
408 | puts(scrbuf); | 409 | puts(scrbuf); |
409 | } | 410 | } |
410 | } | 411 | } |
411 | #undef SHOW_STAT | 412 | # undef SHOW_STAT |
412 | #undef CALC_STAT | 413 | # undef CALC_STAT |
413 | #undef FMT | 414 | # undef FMT |
414 | *lines_rem_p -= i; | 415 | *lines_rem_p -= i; |
415 | } | 416 | } |
416 | #else /* !ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS */ | 417 | #else /* !ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS */ |
417 | #define display_cpus(scr_width, scrbuf, lines_rem) ((void)0) | 418 | # define display_cpus(scr_width, scrbuf, lines_rem) ((void)0) |
418 | #endif | 419 | #endif |
419 | 420 | ||
420 | static unsigned long display_header(int scr_width, int *lines_rem_p) | 421 | 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) | |||
528 | lines_rem--; | 529 | lines_rem--; |
529 | 530 | ||
530 | #if ENABLE_FEATURE_TOP_DECIMALS | 531 | #if ENABLE_FEATURE_TOP_DECIMALS |
531 | #define UPSCALE 1000 | 532 | # define UPSCALE 1000 |
532 | #define CALC_STAT(name, val) div_t name = div((val), 10) | 533 | # define CALC_STAT(name, val) div_t name = div((val), 10) |
533 | #define SHOW_STAT(name) name.quot, '0'+name.rem | 534 | # define SHOW_STAT(name) name.quot, '0'+name.rem |
534 | #define FMT "%3u.%c" | 535 | # define FMT "%3u.%c" |
535 | #else | 536 | #else |
536 | #define UPSCALE 100 | 537 | # define UPSCALE 100 |
537 | #define CALC_STAT(name, val) unsigned name = (val) | 538 | # define CALC_STAT(name, val) unsigned name = (val) |
538 | #define SHOW_STAT(name) name | 539 | # define SHOW_STAT(name) name |
539 | #define FMT "%4u%%" | 540 | # define FMT "%4u%%" |
540 | #endif | 541 | #endif |
541 | /* | 542 | /* |
542 | * MEM% = s->vsz/MemTotal | 543 | * MEM% = s->vsz/MemTotal |
@@ -646,9 +647,9 @@ static void reset_term(void) | |||
646 | tcsetattr_stdin_TCSANOW(&initial_settings); | 647 | tcsetattr_stdin_TCSANOW(&initial_settings); |
647 | if (ENABLE_FEATURE_CLEAN_UP) { | 648 | if (ENABLE_FEATURE_CLEAN_UP) { |
648 | clearmems(); | 649 | clearmems(); |
649 | #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE | 650 | # if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
650 | free(prev_hist); | 651 | free(prev_hist); |
651 | #endif | 652 | # endif |
652 | } | 653 | } |
653 | } | 654 | } |
654 | 655 | ||
@@ -895,7 +896,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
895 | 896 | ||
896 | pfd[0].fd = 0; | 897 | pfd[0].fd = 0; |
897 | pfd[0].events = POLLIN; | 898 | pfd[0].events = POLLIN; |
898 | #endif /* FEATURE_USE_TERMIOS */ | 899 | #endif |
899 | 900 | ||
900 | INIT_G(); | 901 | INIT_G(); |
901 | 902 | ||
@@ -909,10 +910,15 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
909 | #endif | 910 | #endif |
910 | 911 | ||
911 | /* all args are options; -n NUM */ | 912 | /* all args are options; -n NUM */ |
912 | opt_complementary = "-"; | 913 | opt_complementary = "-"; /* options can be specified w/o dash */ |
913 | col = getopt32(argv, "d:n:b", &str_interval, &str_iterations); | 914 | col = getopt32(argv, "d:n:b"IF_FEATURE_TOPMEM("m"), &str_interval, &str_iterations); |
915 | #if ENABLE_FEATURE_TOPMEM | ||
916 | if (col & OPT_m) /* -m (busybox specific) */ | ||
917 | scan_mask = TOPMEM_MASK; | ||
918 | #endif | ||
914 | if (col & OPT_d) { | 919 | if (col & OPT_d) { |
915 | /* work around for "-d 1" -> "-d -1" done by getopt32 */ | 920 | /* work around for "-d 1" -> "-d -1" done by getopt32 |
921 | * (opt_complementary == "-" does this) */ | ||
916 | if (str_interval[0] == '-') | 922 | if (str_interval[0] == '-') |
917 | str_interval++; | 923 | str_interval++; |
918 | /* Need to limit it to not overflow poll timeout */ | 924 | /* Need to limit it to not overflow poll timeout */ |
@@ -934,7 +940,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
934 | 940 | ||
935 | bb_signals(BB_FATAL_SIGS, sig_catcher); | 941 | bb_signals(BB_FATAL_SIGS, sig_catcher); |
936 | tcsetattr_stdin_TCSANOW(&new_settings); | 942 | tcsetattr_stdin_TCSANOW(&new_settings); |
937 | #endif /* FEATURE_USE_TERMIOS */ | 943 | #endif |
938 | 944 | ||
939 | #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE | 945 | #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
940 | sort_function[0] = pcpu_sort; | 946 | sort_function[0] = pcpu_sort; |
@@ -942,7 +948,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
942 | sort_function[2] = time_sort; | 948 | sort_function[2] = time_sort; |
943 | #else | 949 | #else |
944 | sort_function[0] = mem_sort; | 950 | sort_function[0] = mem_sort; |
945 | #endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */ | 951 | #endif |
946 | 952 | ||
947 | while (1) { | 953 | while (1) { |
948 | procps_status_t *p = NULL; | 954 | procps_status_t *p = NULL; |
@@ -956,7 +962,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
956 | sleep(interval); | 962 | sleep(interval); |
957 | continue; | 963 | continue; |
958 | } | 964 | } |
959 | #endif /* FEATURE_USE_TERMIOS */ | 965 | #endif |
960 | if (col > LINE_BUF_SIZE-2) /* +2 bytes for '\n', NUL, */ | 966 | if (col > LINE_BUF_SIZE-2) /* +2 bytes for '\n', NUL, */ |
961 | col = LINE_BUF_SIZE-2; | 967 | col = LINE_BUF_SIZE-2; |
962 | 968 | ||
@@ -1015,7 +1021,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1015 | qsort(top, ntop, sizeof(top_status_t), (void*)mult_lvl_cmp); | 1021 | qsort(top, ntop, sizeof(top_status_t), (void*)mult_lvl_cmp); |
1016 | #else | 1022 | #else |
1017 | qsort(top, ntop, sizeof(top_status_t), (void*)(sort_function[0])); | 1023 | qsort(top, ntop, sizeof(top_status_t), (void*)(sort_function[0])); |
1018 | #endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */ | 1024 | #endif |
1019 | } | 1025 | } |
1020 | #if ENABLE_FEATURE_TOPMEM | 1026 | #if ENABLE_FEATURE_TOPMEM |
1021 | else { /* TOPMEM */ | 1027 | else { /* TOPMEM */ |
@@ -1058,12 +1064,12 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1058 | if (c == 'm') { | 1064 | if (c == 'm') { |
1059 | IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) | 1065 | IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) |
1060 | sort_function[0] = mem_sort; | 1066 | sort_function[0] = mem_sort; |
1061 | #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE | 1067 | # if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
1062 | sort_function[1] = pcpu_sort; | 1068 | sort_function[1] = pcpu_sort; |
1063 | sort_function[2] = time_sort; | 1069 | sort_function[2] = time_sort; |
1064 | #endif | 1070 | # endif |
1065 | } | 1071 | } |
1066 | #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE | 1072 | # if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
1067 | if (c == 'p') { | 1073 | if (c == 'p') { |
1068 | IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) | 1074 | IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) |
1069 | sort_function[0] = pcpu_sort; | 1075 | sort_function[0] = pcpu_sort; |
@@ -1076,7 +1082,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1076 | sort_function[1] = mem_sort; | 1082 | sort_function[1] = mem_sort; |
1077 | sort_function[2] = pcpu_sort; | 1083 | sort_function[2] = pcpu_sort; |
1078 | } | 1084 | } |
1079 | #if ENABLE_FEATURE_TOPMEM | 1085 | # if ENABLE_FEATURE_TOPMEM |
1080 | if (c == 's') { | 1086 | if (c == 's') { |
1081 | scan_mask = TOPMEM_MASK; | 1087 | scan_mask = TOPMEM_MASK; |
1082 | free(prev_hist); | 1088 | free(prev_hist); |
@@ -1086,8 +1092,8 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1086 | } | 1092 | } |
1087 | if (c == 'r') | 1093 | if (c == 'r') |
1088 | inverted ^= 1; | 1094 | inverted ^= 1; |
1089 | #endif | 1095 | # endif |
1090 | #if ENABLE_FEATURE_TOP_SMP_CPU | 1096 | # if ENABLE_FEATURE_TOP_SMP_CPU |
1091 | /* procps-2.0.18 uses 'C', 3.2.7 uses '1' */ | 1097 | /* procps-2.0.18 uses 'C', 3.2.7 uses '1' */ |
1092 | if (c == 'c' || c == '1') { | 1098 | if (c == 'c' || c == '1') { |
1093 | /* User wants to toggle per cpu <> aggregate */ | 1099 | /* User wants to toggle per cpu <> aggregate */ |
@@ -1104,8 +1110,8 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1104 | smp_cpu_info = !smp_cpu_info; | 1110 | smp_cpu_info = !smp_cpu_info; |
1105 | get_jiffy_counts(); | 1111 | get_jiffy_counts(); |
1106 | } | 1112 | } |
1107 | #endif | 1113 | # endif |
1108 | #endif | 1114 | # endif |
1109 | } | 1115 | } |
1110 | #endif /* FEATURE_USE_TERMIOS */ | 1116 | #endif /* FEATURE_USE_TERMIOS */ |
1111 | } /* end of "while (1)" */ | 1117 | } /* end of "while (1)" */ |