aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-09-11 23:26:42 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-09-11 23:26:42 +0200
commit00528822004e5763c669e58191f10c5202f679b5 (patch)
treec60a30ca27a190bb09f6d4fe3948c56e0aef3583
parent56573cb4f7393fdb320660a5c258c72688a74f64 (diff)
downloadbusybox-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--TODO23
-rw-r--r--include/usage.h2
-rw-r--r--libbb/getopt32.c14
-rw-r--r--procps/top.c108
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
320 320
321Unicode work needed: 321Unicode work needed:
322 322
323Unicode support uses libc multibyte functions if LOCALE_SUPPORT is on
324(in this case, the code will also support many more encodings),
325or uses a limited subset of re-implemented multibyte functions
326which only understand "one byte == one char" and unicode.
327This is useful if you build against uclibc with locale support disabled.
328
329Unicode-dependent applets must call check_unicode_in_env() when they
330begin executing.
331
332Applet code may conditionalize on FEATURE_ASSUME_UNICODE
333in order to use more efficient code if unicode support is not requested.
334
335Available functions (if you need more, implement them in libbb/unicode.c
336so that they work without LOCALE_SUPPORT too):
337
338int bb_mbstrlen(str) - multibyte-aware strlen
339size_t mbstowcs(wdest, src, n)
340size_t wcstombs(dest, wsrc, n)
341size_t wcrtomb(str, wc, wstate)
342int iswspace(wc)
343int iswalnum(wc)
344int iswpunct(wc)
345
323Applets which only need to align columns on screen correctly: 346Applets which only need to align columns on screen correctly:
324 347
325ls - already done, use source as an example 348ls - 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
148Special characters: 148Special 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
420static unsigned long display_header(int scr_width, int *lines_rem_p) 421static 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)" */