diff options
Diffstat (limited to 'procps')
-rw-r--r-- | procps/free.c | 7 | ||||
-rw-r--r-- | procps/fuser.c | 3 | ||||
-rw-r--r-- | procps/iostat.c | 3 | ||||
-rw-r--r-- | procps/kill.c | 10 | ||||
-rw-r--r-- | procps/mpstat.c | 1 | ||||
-rw-r--r-- | procps/pgrep.c | 6 | ||||
-rw-r--r-- | procps/pidof.c | 4 | ||||
-rw-r--r-- | procps/pmap.c | 4 | ||||
-rw-r--r-- | procps/powertop.c | 14 | ||||
-rw-r--r-- | procps/ps.c | 185 | ||||
-rw-r--r-- | procps/pstree.c | 6 | ||||
-rw-r--r-- | procps/pwdx.c | 6 | ||||
-rw-r--r-- | procps/sysctl.c | 64 | ||||
-rw-r--r-- | procps/top.c | 19 | ||||
-rw-r--r-- | procps/uptime.c | 2 | ||||
-rw-r--r-- | procps/watch.c | 6 |
16 files changed, 160 insertions, 180 deletions
diff --git a/procps/free.c b/procps/free.c index 618664e08..b57e4a322 100644 --- a/procps/free.c +++ b/procps/free.c | |||
@@ -15,7 +15,7 @@ | |||
15 | //config: memory in the system, as well as the buffers used by the kernel. | 15 | //config: memory in the system, as well as the buffers used by the kernel. |
16 | //config: The shared memory column should be ignored; it is obsolete. | 16 | //config: The shared memory column should be ignored; it is obsolete. |
17 | 17 | ||
18 | //applet:IF_FREE(APPLET(free, BB_DIR_USR_BIN, BB_SUID_DROP)) | 18 | //applet:IF_FREE(APPLET_NOEXEC(free, free, BB_DIR_USR_BIN, BB_SUID_DROP, free)) |
19 | 19 | ||
20 | //kbuild:lib-$(CONFIG_FREE) += free.o | 20 | //kbuild:lib-$(CONFIG_FREE) += free.o |
21 | 21 | ||
@@ -47,7 +47,10 @@ struct globals { | |||
47 | #endif | 47 | #endif |
48 | } FIX_ALIASING; | 48 | } FIX_ALIASING; |
49 | #define G (*(struct globals*)bb_common_bufsiz1) | 49 | #define G (*(struct globals*)bb_common_bufsiz1) |
50 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | 50 | #define INIT_G() do { \ |
51 | setup_common_bufsiz(); \ | ||
52 | /* NB: noexec applet - globals not zeroed */ \ | ||
53 | } while (0) | ||
51 | 54 | ||
52 | 55 | ||
53 | static unsigned long long scale(unsigned long d) | 56 | static unsigned long long scale(unsigned long d) |
diff --git a/procps/fuser.c b/procps/fuser.c index 2585a4203..418f57b57 100644 --- a/procps/fuser.c +++ b/procps/fuser.c | |||
@@ -299,8 +299,7 @@ int fuser_main(int argc UNUSED_PARAM, char **argv) | |||
299 | break; | 299 | break; |
300 | } | 300 | } |
301 | 301 | ||
302 | opt_complementary = "-1"; /* at least one param */ | 302 | getopt32(argv, "^" OPTION_STRING "\0" "-1"/*at least one arg*/); |
303 | getopt32(argv, OPTION_STRING); | ||
304 | argv += optind; | 303 | argv += optind; |
305 | 304 | ||
306 | pp = argv; | 305 | pp = argv; |
diff --git a/procps/iostat.c b/procps/iostat.c index 6a39c324f..050625f57 100644 --- a/procps/iostat.c +++ b/procps/iostat.c | |||
@@ -418,8 +418,7 @@ int iostat_main(int argc UNUSED_PARAM, char **argv) | |||
418 | 418 | ||
419 | /* Parse and process arguments */ | 419 | /* Parse and process arguments */ |
420 | /* -k and -m are mutually exclusive */ | 420 | /* -k and -m are mutually exclusive */ |
421 | opt_complementary = "k--m:m--k"; | 421 | opt = getopt32(argv, "^" "cdtzkm" "\0" "k--m:m--k"); |
422 | opt = getopt32(argv, "cdtzkm"); | ||
423 | if (!(opt & (OPT_c + OPT_d))) | 422 | if (!(opt & (OPT_c + OPT_d))) |
424 | /* Default is -cd */ | 423 | /* Default is -cd */ |
425 | opt |= OPT_c + OPT_d; | 424 | opt |= OPT_c + OPT_d; |
diff --git a/procps/kill.c b/procps/kill.c index 09beefb2d..0ddae2f70 100644 --- a/procps/kill.c +++ b/procps/kill.c | |||
@@ -32,10 +32,10 @@ | |||
32 | //config: in its own session, so it won't kill the shell that is running | 32 | //config: in its own session, so it won't kill the shell that is running |
33 | //config: the script it was called from. | 33 | //config: the script it was called from. |
34 | 34 | ||
35 | //applet:IF_KILL(APPLET(kill, BB_DIR_BIN, BB_SUID_DROP)) | 35 | //applet:IF_KILL( APPLET_NOFORK(kill, kill, BB_DIR_BIN, BB_SUID_DROP, kill)) |
36 | // APPLET_ODDNAME:name main location suid_type help | 36 | // APPLET_NOFORK:name main location suid_type help |
37 | //applet:IF_KILLALL( APPLET_ODDNAME(killall, kill, BB_DIR_USR_BIN, BB_SUID_DROP, killall)) | 37 | //applet:IF_KILLALL( APPLET_NOFORK(killall, kill, BB_DIR_USR_BIN, BB_SUID_DROP, killall)) |
38 | //applet:IF_KILLALL5(APPLET_ODDNAME(killall5, kill, BB_DIR_USR_SBIN, BB_SUID_DROP, killall5)) | 38 | //applet:IF_KILLALL5(APPLET_NOFORK(killall5, kill, BB_DIR_USR_SBIN, BB_SUID_DROP, killall5)) |
39 | 39 | ||
40 | //kbuild:lib-$(CONFIG_KILL) += kill.o | 40 | //kbuild:lib-$(CONFIG_KILL) += kill.o |
41 | //kbuild:lib-$(CONFIG_KILLALL) += kill.o | 41 | //kbuild:lib-$(CONFIG_KILLALL) += kill.o |
@@ -87,7 +87,7 @@ | |||
87 | * + we can't use xfunc here | 87 | * + we can't use xfunc here |
88 | * + we can't use applet_name | 88 | * + we can't use applet_name |
89 | * + we can't use bb_show_usage | 89 | * + we can't use bb_show_usage |
90 | * (Above doesn't apply for killall[5] cases) | 90 | * (doesn't apply for killall[5], still should be careful b/c NOFORK) |
91 | * | 91 | * |
92 | * kill %n gets translated into kill ' -<process group>' by shell (note space!) | 92 | * kill %n gets translated into kill ' -<process group>' by shell (note space!) |
93 | * This is needed to avoid collision with kill -9 ... syntax | 93 | * This is needed to avoid collision with kill -9 ... syntax |
diff --git a/procps/mpstat.c b/procps/mpstat.c index 05a3f3ff3..c6279f9d8 100644 --- a/procps/mpstat.c +++ b/procps/mpstat.c | |||
@@ -8,6 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | //applet:IF_MPSTAT(APPLET(mpstat, BB_DIR_BIN, BB_SUID_DROP)) | 10 | //applet:IF_MPSTAT(APPLET(mpstat, BB_DIR_BIN, BB_SUID_DROP)) |
11 | /* shouldn't be noexec: "mpstat INTERVAL" runs indefinitely */ | ||
11 | 12 | ||
12 | //kbuild:lib-$(CONFIG_MPSTAT) += mpstat.o | 13 | //kbuild:lib-$(CONFIG_MPSTAT) += mpstat.o |
13 | 14 | ||
diff --git a/procps/pgrep.c b/procps/pgrep.c index a3ca9e295..a16a6e959 100644 --- a/procps/pgrep.c +++ b/procps/pgrep.c | |||
@@ -18,9 +18,13 @@ | |||
18 | //config: help | 18 | //config: help |
19 | //config: Send signals to processes by name. | 19 | //config: Send signals to processes by name. |
20 | 20 | ||
21 | //applet:IF_PGREP(APPLET(pgrep, BB_DIR_USR_BIN, BB_SUID_DROP)) | 21 | //applet:IF_PGREP(APPLET_ODDNAME(pgrep, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pgrep)) |
22 | // APPLET_ODDNAME:name main location suid_type help | 22 | // APPLET_ODDNAME:name main location suid_type help |
23 | //applet:IF_PKILL(APPLET_ODDNAME(pkill, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pkill)) | 23 | //applet:IF_PKILL(APPLET_ODDNAME(pkill, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pkill)) |
24 | /* can't be noexec: can find _itself_ under wrong name, since after fork only, | ||
25 | * /proc/PID/cmdline and comm are wrong! Can fix comm (prctl(PR_SET_NAME)), | ||
26 | * but cmdline? | ||
27 | */ | ||
24 | 28 | ||
25 | //kbuild:lib-$(CONFIG_PGREP) += pgrep.o | 29 | //kbuild:lib-$(CONFIG_PGREP) += pgrep.o |
26 | //kbuild:lib-$(CONFIG_PKILL) += pgrep.o | 30 | //kbuild:lib-$(CONFIG_PKILL) += pgrep.o |
diff --git a/procps/pidof.c b/procps/pidof.c index 41247a02c..98d7949f8 100644 --- a/procps/pidof.c +++ b/procps/pidof.c | |||
@@ -30,6 +30,10 @@ | |||
30 | //config: of the pidof, in other words the calling shell or shell script. | 30 | //config: of the pidof, in other words the calling shell or shell script. |
31 | 31 | ||
32 | //applet:IF_PIDOF(APPLET(pidof, BB_DIR_BIN, BB_SUID_DROP)) | 32 | //applet:IF_PIDOF(APPLET(pidof, BB_DIR_BIN, BB_SUID_DROP)) |
33 | /* can't be noexec: can find _itself_ under wrong name, since after fork only, | ||
34 | * /proc/PID/cmdline and comm are wrong! Can fix comm (prctl(PR_SET_NAME)), | ||
35 | * but cmdline? | ||
36 | */ | ||
33 | 37 | ||
34 | //kbuild:lib-$(CONFIG_PIDOF) += pidof.o | 38 | //kbuild:lib-$(CONFIG_PIDOF) += pidof.o |
35 | 39 | ||
diff --git a/procps/pmap.c b/procps/pmap.c index c8f728897..5c2d1ad59 100644 --- a/procps/pmap.c +++ b/procps/pmap.c | |||
@@ -18,7 +18,7 @@ | |||
18 | //kbuild:lib-$(CONFIG_PMAP) += pmap.o | 18 | //kbuild:lib-$(CONFIG_PMAP) += pmap.o |
19 | 19 | ||
20 | //usage:#define pmap_trivial_usage | 20 | //usage:#define pmap_trivial_usage |
21 | //usage: "[-xq] PID" | 21 | //usage: "[-xq] PID..." |
22 | //usage:#define pmap_full_usage "\n\n" | 22 | //usage:#define pmap_full_usage "\n\n" |
23 | //usage: "Display process memory usage" | 23 | //usage: "Display process memory usage" |
24 | //usage: "\n" | 24 | //usage: "\n" |
@@ -96,7 +96,7 @@ int pmap_main(int argc UNUSED_PARAM, char **argv) | |||
96 | unsigned opts; | 96 | unsigned opts; |
97 | int ret; | 97 | int ret; |
98 | 98 | ||
99 | opts = getopt32(argv, "xq"); | 99 | opts = getopt32(argv, "^" "xq" "\0" "-1"); /* min one arg */ |
100 | argv += optind; | 100 | argv += optind; |
101 | 101 | ||
102 | ret = 0; | 102 | ret = 0; |
diff --git a/procps/powertop.c b/procps/powertop.c index ebd659bdb..5d522bf91 100644 --- a/procps/powertop.c +++ b/procps/powertop.c | |||
@@ -8,11 +8,6 @@ | |||
8 | * | 8 | * |
9 | * Licensed under GPLv2, see file LICENSE in this source tree. | 9 | * Licensed under GPLv2, see file LICENSE in this source tree. |
10 | */ | 10 | */ |
11 | |||
12 | //applet:IF_POWERTOP(APPLET(powertop, BB_DIR_USR_SBIN, BB_SUID_DROP)) | ||
13 | |||
14 | //kbuild:lib-$(CONFIG_POWERTOP) += powertop.o | ||
15 | |||
16 | //config:config POWERTOP | 11 | //config:config POWERTOP |
17 | //config: bool "powertop (9.1 kb)" | 12 | //config: bool "powertop (9.1 kb)" |
18 | //config: default y | 13 | //config: default y |
@@ -27,6 +22,10 @@ | |||
27 | //config: Without this, powertop will only refresh display every 10 seconds. | 22 | //config: Without this, powertop will only refresh display every 10 seconds. |
28 | //config: No keyboard commands will work, only ^C to terminate. | 23 | //config: No keyboard commands will work, only ^C to terminate. |
29 | 24 | ||
25 | //applet:IF_POWERTOP(APPLET(powertop, BB_DIR_USR_SBIN, BB_SUID_DROP)) | ||
26 | |||
27 | //kbuild:lib-$(CONFIG_POWERTOP) += powertop.o | ||
28 | |||
30 | // XXX This should be configurable | 29 | // XXX This should be configurable |
31 | #define ENABLE_FEATURE_POWERTOP_PROCIRQ 1 | 30 | #define ENABLE_FEATURE_POWERTOP_PROCIRQ 1 |
32 | 31 | ||
@@ -718,7 +717,7 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv) | |||
718 | set_termios_to_raw(STDIN_FILENO, &G.init_settings, TERMIOS_CLEAR_ISIG); | 717 | set_termios_to_raw(STDIN_FILENO, &G.init_settings, TERMIOS_CLEAR_ISIG); |
719 | bb_signals(BB_FATAL_SIGS, sig_handler); | 718 | bb_signals(BB_FATAL_SIGS, sig_handler); |
720 | /* So we don't forget to reset term settings */ | 719 | /* So we don't forget to reset term settings */ |
721 | atexit(reset_term); | 720 | die_func = reset_term; |
722 | #endif | 721 | #endif |
723 | 722 | ||
724 | /* Collect initial data */ | 723 | /* Collect initial data */ |
@@ -855,6 +854,9 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv) | |||
855 | } /* for (;;) */ | 854 | } /* for (;;) */ |
856 | 855 | ||
857 | bb_putchar('\n'); | 856 | bb_putchar('\n'); |
857 | #if ENABLE_FEATURE_POWERTOP_INTERACTIVE | ||
858 | reset_term(); | ||
859 | #endif | ||
858 | 860 | ||
859 | return EXIT_SUCCESS; | 861 | return EXIT_SUCCESS; |
860 | } | 862 | } |
diff --git a/procps/ps.c b/procps/ps.c index 3e83a3e03..742d1715e 100644 --- a/procps/ps.c +++ b/procps/ps.c | |||
@@ -15,26 +15,26 @@ | |||
15 | //config: ps gives a snapshot of the current processes. | 15 | //config: ps gives a snapshot of the current processes. |
16 | //config: | 16 | //config: |
17 | //config:config FEATURE_PS_WIDE | 17 | //config:config FEATURE_PS_WIDE |
18 | //config: bool "Enable wide output option (-w)" | 18 | //config: bool "Enable wide output (-w)" |
19 | //config: default y | 19 | //config: default y |
20 | //config: depends on PS && !DESKTOP | 20 | //config: depends on (PS || MINIPS) && !DESKTOP |
21 | //config: help | 21 | //config: help |
22 | //config: Support argument 'w' for wide output. | 22 | //config: Support argument 'w' for wide output. |
23 | //config: If given once, 132 chars are printed, and if given more | 23 | //config: If given once, 132 chars are printed, and if given more |
24 | //config: than once, the length is unlimited. | 24 | //config: than once, the length is unlimited. |
25 | //config: | 25 | //config: |
26 | //config:config FEATURE_PS_LONG | 26 | //config:config FEATURE_PS_LONG |
27 | //config: bool "Enable long output option (-l)" | 27 | //config: bool "Enable long output (-l)" |
28 | //config: default y | 28 | //config: default y |
29 | //config: depends on PS && !DESKTOP | 29 | //config: depends on (PS || MINIPS) && !DESKTOP |
30 | //config: help | 30 | //config: help |
31 | //config: Support argument 'l' for long output. | 31 | //config: Support argument 'l' for long output. |
32 | //config: Adds fields PPID, RSS, START, TIME & TTY | 32 | //config: Adds fields PPID, RSS, START, TIME & TTY |
33 | //config: | 33 | //config: |
34 | //config:config FEATURE_PS_TIME | 34 | //config:config FEATURE_PS_TIME |
35 | //config: bool "Support -o time and -o etime output specifiers" | 35 | //config: bool "Enable -o time and -o etime specifiers" |
36 | //config: default y | 36 | //config: default y |
37 | //config: depends on PS && DESKTOP | 37 | //config: depends on (PS || MINIPS) && DESKTOP |
38 | //config: select PLATFORM_LINUX | 38 | //config: select PLATFORM_LINUX |
39 | //config: | 39 | //config: |
40 | //config:config FEATURE_PS_UNUSUAL_SYSTEMS | 40 | //config:config FEATURE_PS_UNUSUAL_SYSTEMS |
@@ -46,13 +46,16 @@ | |||
46 | //config: (if you are on Linux 2.4.0+ and use ELF, you don't need this) | 46 | //config: (if you are on Linux 2.4.0+ and use ELF, you don't need this) |
47 | //config: | 47 | //config: |
48 | //config:config FEATURE_PS_ADDITIONAL_COLUMNS | 48 | //config:config FEATURE_PS_ADDITIONAL_COLUMNS |
49 | //config: bool "Support -o rgroup, -o ruser, -o nice specifiers" | 49 | //config: bool "Enable -o rgroup, -o ruser, -o nice specifiers" |
50 | //config: default y | 50 | //config: default y |
51 | //config: depends on PS && DESKTOP | 51 | //config: depends on (PS || MINIPS) && DESKTOP |
52 | 52 | ||
53 | //applet:IF_PS(APPLET(ps, BB_DIR_BIN, BB_SUID_DROP)) | 53 | // APPLET_NOEXEC:name main location suid_type help |
54 | //applet:IF_PS( APPLET_NOEXEC(ps, ps, BB_DIR_BIN, BB_SUID_DROP, ps)) | ||
55 | //applet:IF_MINIPS(APPLET_NOEXEC(minips, ps, BB_DIR_BIN, BB_SUID_DROP, ps)) | ||
54 | 56 | ||
55 | //kbuild:lib-$(CONFIG_PS) += ps.o | 57 | //kbuild:lib-$(CONFIG_PS) += ps.o |
58 | //kbuild:lib-$(CONFIG_MINIPS) += ps.o | ||
56 | 59 | ||
57 | //usage:#if ENABLE_DESKTOP | 60 | //usage:#if ENABLE_DESKTOP |
58 | //usage: | 61 | //usage: |
@@ -144,12 +147,6 @@ static unsigned long get_uptime(void) | |||
144 | #endif | 147 | #endif |
145 | 148 | ||
146 | #if ENABLE_DESKTOP | 149 | #if ENABLE_DESKTOP |
147 | |||
148 | #include <sys/times.h> /* for times() */ | ||
149 | #ifndef AT_CLKTCK | ||
150 | # define AT_CLKTCK 17 | ||
151 | #endif | ||
152 | |||
153 | /* TODO: | 150 | /* TODO: |
154 | * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html | 151 | * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html |
155 | * specifies (for XSI-conformant systems) following default columns | 152 | * specifies (for XSI-conformant systems) following default columns |
@@ -186,7 +183,9 @@ struct globals { | |||
186 | char *buffer; | 183 | char *buffer; |
187 | unsigned terminal_width; | 184 | unsigned terminal_width; |
188 | #if ENABLE_FEATURE_PS_TIME | 185 | #if ENABLE_FEATURE_PS_TIME |
186 | # if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS || !defined(__linux__) | ||
189 | unsigned kernel_HZ; | 187 | unsigned kernel_HZ; |
188 | # endif | ||
190 | unsigned long seconds_since_boot; | 189 | unsigned long seconds_since_boot; |
191 | #endif | 190 | #endif |
192 | } FIX_ALIASING; | 191 | } FIX_ALIASING; |
@@ -197,91 +196,15 @@ struct globals { | |||
197 | #define need_flags (G.need_flags ) | 196 | #define need_flags (G.need_flags ) |
198 | #define buffer (G.buffer ) | 197 | #define buffer (G.buffer ) |
199 | #define terminal_width (G.terminal_width ) | 198 | #define terminal_width (G.terminal_width ) |
200 | #define kernel_HZ (G.kernel_HZ ) | ||
201 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | 199 | #define INIT_G() do { setup_common_bufsiz(); } while (0) |
202 | 200 | ||
203 | #if ENABLE_FEATURE_PS_TIME | 201 | #if ENABLE_FEATURE_PS_TIME |
204 | /* for ELF executables, notes are pushed before environment and args */ | 202 | # if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS || !defined(__linux__) |
205 | static uintptr_t find_elf_note(uintptr_t findme) | 203 | # define get_kernel_HZ() (G.kernel_HZ) |
206 | { | 204 | # else |
207 | uintptr_t *ep = (uintptr_t *) environ; | 205 | /* non-ancient Linux standardized on 100 for "times" freq */ |
208 | 206 | # define get_kernel_HZ() ((unsigned)100) | |
209 | while (*ep++) | 207 | # endif |
210 | continue; | ||
211 | while (*ep) { | ||
212 | if (ep[0] == findme) { | ||
213 | return ep[1]; | ||
214 | } | ||
215 | ep += 2; | ||
216 | } | ||
217 | return -1; | ||
218 | } | ||
219 | |||
220 | #if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS | ||
221 | static unsigned get_HZ_by_waiting(void) | ||
222 | { | ||
223 | struct timeval tv1, tv2; | ||
224 | unsigned t1, t2, r, hz; | ||
225 | unsigned cnt = cnt; /* for compiler */ | ||
226 | int diff; | ||
227 | |||
228 | r = 0; | ||
229 | |||
230 | /* Wait for times() to reach new tick */ | ||
231 | t1 = times(NULL); | ||
232 | do { | ||
233 | t2 = times(NULL); | ||
234 | } while (t2 == t1); | ||
235 | gettimeofday(&tv2, NULL); | ||
236 | |||
237 | do { | ||
238 | t1 = t2; | ||
239 | tv1.tv_usec = tv2.tv_usec; | ||
240 | |||
241 | /* Wait exactly one times() tick */ | ||
242 | do { | ||
243 | t2 = times(NULL); | ||
244 | } while (t2 == t1); | ||
245 | gettimeofday(&tv2, NULL); | ||
246 | |||
247 | /* Calculate ticks per sec, rounding up to even */ | ||
248 | diff = tv2.tv_usec - tv1.tv_usec; | ||
249 | if (diff <= 0) diff += 1000000; | ||
250 | hz = 1000000u / (unsigned)diff; | ||
251 | hz = (hz+1) & ~1; | ||
252 | |||
253 | /* Count how many same hz values we saw */ | ||
254 | if (r != hz) { | ||
255 | r = hz; | ||
256 | cnt = 0; | ||
257 | } | ||
258 | cnt++; | ||
259 | } while (cnt < 3); /* exit if saw 3 same values */ | ||
260 | |||
261 | return r; | ||
262 | } | ||
263 | #else | ||
264 | static inline unsigned get_HZ_by_waiting(void) | ||
265 | { | ||
266 | /* Better method? */ | ||
267 | return 100; | ||
268 | } | ||
269 | #endif | ||
270 | |||
271 | static unsigned get_kernel_HZ(void) | ||
272 | { | ||
273 | if (kernel_HZ) | ||
274 | return kernel_HZ; | ||
275 | |||
276 | /* Works for ELF only, Linux 2.4.0+ */ | ||
277 | kernel_HZ = find_elf_note(AT_CLKTCK); | ||
278 | if (kernel_HZ == (unsigned)-1) | ||
279 | kernel_HZ = get_HZ_by_waiting(); | ||
280 | |||
281 | G.seconds_since_boot = get_uptime(); | ||
282 | |||
283 | return kernel_HZ; | ||
284 | } | ||
285 | #endif | 208 | #endif |
286 | 209 | ||
287 | /* Print value to buf, max size+1 chars (including trailing '\0') */ | 210 | /* Print value to buf, max size+1 chars (including trailing '\0') */ |
@@ -379,52 +302,71 @@ static void func_tty(char *buf, int size, const procps_status_t *ps) | |||
379 | #endif | 302 | #endif |
380 | 303 | ||
381 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS | 304 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS |
382 | |||
383 | static void func_rgroup(char *buf, int size, const procps_status_t *ps) | 305 | static void func_rgroup(char *buf, int size, const procps_status_t *ps) |
384 | { | 306 | { |
385 | safe_strncpy(buf, get_cached_groupname(ps->rgid), size+1); | 307 | safe_strncpy(buf, get_cached_groupname(ps->rgid), size+1); |
386 | } | 308 | } |
387 | |||
388 | static void func_ruser(char *buf, int size, const procps_status_t *ps) | 309 | static void func_ruser(char *buf, int size, const procps_status_t *ps) |
389 | { | 310 | { |
390 | safe_strncpy(buf, get_cached_username(ps->ruid), size+1); | 311 | safe_strncpy(buf, get_cached_username(ps->ruid), size+1); |
391 | } | 312 | } |
392 | |||
393 | static void func_nice(char *buf, int size, const procps_status_t *ps) | 313 | static void func_nice(char *buf, int size, const procps_status_t *ps) |
394 | { | 314 | { |
395 | sprintf(buf, "%*d", size, ps->niceness); | 315 | sprintf(buf, "%*d", size, ps->niceness); |
396 | } | 316 | } |
397 | |||
398 | #endif | 317 | #endif |
399 | 318 | ||
400 | #if ENABLE_FEATURE_PS_TIME | 319 | #if ENABLE_FEATURE_PS_TIME |
320 | static void format_time(char *buf, int size, unsigned long tt) | ||
321 | { | ||
322 | unsigned ff; | ||
401 | 323 | ||
324 | /* Used to show "14453:50" if tt is large. Ugly. | ||
325 | * procps-ng 3.3.10 uses "[[dd-]hh:]mm:ss" format. | ||
326 | * TODO: switch to that? | ||
327 | */ | ||
328 | |||
329 | /* Formatting for 5-char TIME column. | ||
330 | * NB: "size" is not always 5: ELAPSED is wider (7), | ||
331 | * not taking advantage of that (yet?). | ||
332 | */ | ||
333 | ff = tt % 60; | ||
334 | tt /= 60; | ||
335 | if (tt < 60) { | ||
336 | snprintf(buf, size+1, "%2u:%02u", (unsigned)tt, ff); | ||
337 | return; | ||
338 | } | ||
339 | ff = tt % 60; | ||
340 | tt /= 60; | ||
341 | if (tt < 24) { | ||
342 | snprintf(buf, size+1, "%2uh%02u", (unsigned)tt, ff); | ||
343 | return; | ||
344 | } | ||
345 | ff = tt % 24; | ||
346 | tt /= 24; | ||
347 | if (tt < 100) { | ||
348 | snprintf(buf, size+1, "%2ud%02u", (unsigned)tt, ff); | ||
349 | return; | ||
350 | } | ||
351 | snprintf(buf, size+1, "%4lud", tt); | ||
352 | } | ||
402 | static void func_etime(char *buf, int size, const procps_status_t *ps) | 353 | static void func_etime(char *buf, int size, const procps_status_t *ps) |
403 | { | 354 | { |
404 | /* elapsed time [[dd-]hh:]mm:ss; here only mm:ss */ | 355 | /* elapsed time [[dd-]hh:]mm:ss; here only mm:ss */ |
405 | unsigned long mm; | 356 | unsigned long mm; |
406 | unsigned ss; | ||
407 | 357 | ||
408 | mm = ps->start_time / get_kernel_HZ(); | 358 | mm = ps->start_time / get_kernel_HZ(); |
409 | /* must be after get_kernel_HZ()! */ | ||
410 | mm = G.seconds_since_boot - mm; | 359 | mm = G.seconds_since_boot - mm; |
411 | ss = mm % 60; | 360 | format_time(buf, size, mm); |
412 | mm /= 60; | ||
413 | snprintf(buf, size+1, "%3lu:%02u", mm, ss); | ||
414 | } | 361 | } |
415 | |||
416 | static void func_time(char *buf, int size, const procps_status_t *ps) | 362 | static void func_time(char *buf, int size, const procps_status_t *ps) |
417 | { | 363 | { |
418 | /* cumulative time [[dd-]hh:]mm:ss; here only mm:ss */ | 364 | /* cumulative time [[dd-]hh:]mm:ss; here only mm:ss */ |
419 | unsigned long mm; | 365 | unsigned long mm; |
420 | unsigned ss; | ||
421 | 366 | ||
422 | mm = (ps->utime + ps->stime) / get_kernel_HZ(); | 367 | mm = (ps->utime + ps->stime) / get_kernel_HZ(); |
423 | ss = mm % 60; | 368 | format_time(buf, size, mm); |
424 | mm /= 60; | ||
425 | snprintf(buf, size+1, "%3lu:%02u", mm, ss); | ||
426 | } | 369 | } |
427 | |||
428 | #endif | 370 | #endif |
429 | 371 | ||
430 | #if ENABLE_SELINUX | 372 | #if ENABLE_SELINUX |
@@ -465,7 +407,7 @@ static const ps_out_t out_spec[] = { | |||
465 | // { 5 , "pcpu" ,"%CPU" ,func_pcpu ,PSSCAN_ }, | 407 | // { 5 , "pcpu" ,"%CPU" ,func_pcpu ,PSSCAN_ }, |
466 | #endif | 408 | #endif |
467 | #if ENABLE_FEATURE_PS_TIME | 409 | #if ENABLE_FEATURE_PS_TIME |
468 | { 6 , "time" ,"TIME" ,func_time ,PSSCAN_STIME | PSSCAN_UTIME }, | 410 | { 5 , "time" ,"TIME" ,func_time ,PSSCAN_STIME | PSSCAN_UTIME }, |
469 | #endif | 411 | #endif |
470 | #if !ENABLE_PLATFORM_MINGW32 | 412 | #if !ENABLE_PLATFORM_MINGW32 |
471 | { 6 , "tty" ,"TT" ,func_tty ,PSSCAN_TTY }, | 413 | { 6 , "tty" ,"TT" ,func_tty ,PSSCAN_TTY }, |
@@ -641,6 +583,12 @@ int ps_main(int argc UNUSED_PARAM, char **argv) | |||
641 | }; | 583 | }; |
642 | 584 | ||
643 | INIT_G(); | 585 | INIT_G(); |
586 | #if ENABLE_FEATURE_PS_TIME | ||
587 | G.seconds_since_boot = get_uptime(); | ||
588 | # if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS || !defined(__linux__) | ||
589 | G.kernel_HZ = bb_clk_tck(); /* this is sysconf(_SC_CLK_TCK) */ | ||
590 | # endif | ||
591 | #endif | ||
644 | 592 | ||
645 | // POSIX: | 593 | // POSIX: |
646 | // -a Write information for all processes associated with terminals | 594 | // -a Write information for all processes associated with terminals |
@@ -731,9 +679,12 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
731 | # if ENABLE_FEATURE_PS_WIDE | 679 | # if ENABLE_FEATURE_PS_WIDE |
732 | /* -w is a bit complicated */ | 680 | /* -w is a bit complicated */ |
733 | int w_count = 0; | 681 | int w_count = 0; |
734 | opt_complementary = "-:ww"; | 682 | make_all_argv_opts(argv); |
735 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l") | 683 | opts = getopt32(argv, "^" |
736 | "w", &w_count); | 684 | IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")"w" |
685 | "\0" "ww", | ||
686 | &w_count | ||
687 | ); | ||
737 | /* if w is given once, GNU ps sets the width to 132, | 688 | /* if w is given once, GNU ps sets the width to 132, |
738 | * if w is given more than once, it is "unlimited" | 689 | * if w is given more than once, it is "unlimited" |
739 | */ | 690 | */ |
@@ -747,7 +698,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
747 | } | 698 | } |
748 | # else | 699 | # else |
749 | /* -w is not supported, only -Z and/or -T */ | 700 | /* -w is not supported, only -Z and/or -T */ |
750 | opt_complementary = "-"; | 701 | make_all_argv_opts(argv); |
751 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")); | 702 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")); |
752 | # endif | 703 | # endif |
753 | 704 | ||
diff --git a/procps/pstree.c b/procps/pstree.c index 212cda23c..4fda1c21c 100644 --- a/procps/pstree.c +++ b/procps/pstree.c | |||
@@ -9,14 +9,13 @@ | |||
9 | * | 9 | * |
10 | * Licensed under GPLv2, see file LICENSE in this source tree. | 10 | * Licensed under GPLv2, see file LICENSE in this source tree. |
11 | */ | 11 | */ |
12 | |||
13 | //config:config PSTREE | 12 | //config:config PSTREE |
14 | //config: bool "pstree (9.4 kb)" | 13 | //config: bool "pstree (9.4 kb)" |
15 | //config: default y | 14 | //config: default y |
16 | //config: help | 15 | //config: help |
17 | //config: Display a tree of processes. | 16 | //config: Display a tree of processes. |
18 | 17 | ||
19 | //applet:IF_PSTREE(APPLET(pstree, BB_DIR_USR_BIN, BB_SUID_DROP)) | 18 | //applet:IF_PSTREE(APPLET_NOEXEC(pstree, pstree, BB_DIR_USR_BIN, BB_SUID_DROP, pstree)) |
20 | 19 | ||
21 | //kbuild:lib-$(CONFIG_PSTREE) += pstree.o | 20 | //kbuild:lib-$(CONFIG_PSTREE) += pstree.o |
22 | 21 | ||
@@ -387,8 +386,7 @@ int pstree_main(int argc UNUSED_PARAM, char **argv) | |||
387 | 386 | ||
388 | G.output_width = get_terminal_width(0); | 387 | G.output_width = get_terminal_width(0); |
389 | 388 | ||
390 | opt_complementary = "?1"; | 389 | getopt32(argv, "^" "p" "\0" "?1"); |
391 | getopt32(argv, "p"); | ||
392 | argv += optind; | 390 | argv += optind; |
393 | 391 | ||
394 | if (argv[0]) { | 392 | if (argv[0]) { |
diff --git a/procps/pwdx.c b/procps/pwdx.c index dac238950..c72cf804a 100644 --- a/procps/pwdx.c +++ b/procps/pwdx.c | |||
@@ -14,7 +14,7 @@ | |||
14 | //config: help | 14 | //config: help |
15 | //config: Report current working directory of a process | 15 | //config: Report current working directory of a process |
16 | 16 | ||
17 | //applet:IF_PWDX(APPLET(pwdx, BB_DIR_USR_BIN, BB_SUID_DROP)) | 17 | //applet:IF_PWDX(APPLET_NOFORK(pwdx, pwdx, BB_DIR_USR_BIN, BB_SUID_DROP, pwdx)) |
18 | 18 | ||
19 | //kbuild:lib-$(CONFIG_PWDX) += pwdx.o | 19 | //kbuild:lib-$(CONFIG_PWDX) += pwdx.o |
20 | 20 | ||
@@ -28,8 +28,7 @@ | |||
28 | int pwdx_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 28 | int pwdx_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
29 | int pwdx_main(int argc UNUSED_PARAM, char **argv) | 29 | int pwdx_main(int argc UNUSED_PARAM, char **argv) |
30 | { | 30 | { |
31 | opt_complementary = "-1"; | 31 | getopt32(argv, "^" "" "\0" "-1"); |
32 | getopt32(argv, ""); | ||
33 | argv += optind; | 32 | argv += optind; |
34 | 33 | ||
35 | do { | 34 | do { |
@@ -50,6 +49,7 @@ int pwdx_main(int argc UNUSED_PARAM, char **argv) | |||
50 | 49 | ||
51 | sprintf(buf, "/proc/%u/cwd", pid); | 50 | sprintf(buf, "/proc/%u/cwd", pid); |
52 | 51 | ||
52 | /* NOFORK: only one alloc is allowed; must free */ | ||
53 | s = xmalloc_readlink(buf); | 53 | s = xmalloc_readlink(buf); |
54 | // "pwdx /proc/1" says "/proc/1: DIR", not "1: DIR" | 54 | // "pwdx /proc/1" says "/proc/1: DIR", not "1: DIR" |
55 | printf("%s: %s\n", *argv, s ? s : strerror(errno == ENOENT ? ESRCH : errno)); | 55 | printf("%s: %s\n", *argv, s ? s : strerror(errno == ENOENT ? ESRCH : errno)); |
diff --git a/procps/sysctl.c b/procps/sysctl.c index b17f5e896..827e09cce 100644 --- a/procps/sysctl.c +++ b/procps/sysctl.c | |||
@@ -16,22 +16,22 @@ | |||
16 | //config: help | 16 | //config: help |
17 | //config: Configure kernel parameters at runtime. | 17 | //config: Configure kernel parameters at runtime. |
18 | 18 | ||
19 | //applet:IF_BB_SYSCTL(APPLET(sysctl, BB_DIR_SBIN, BB_SUID_DROP)) | 19 | //applet:IF_BB_SYSCTL(APPLET_NOEXEC(sysctl, sysctl, BB_DIR_SBIN, BB_SUID_DROP, sysctl)) |
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_BB_SYSCTL) += sysctl.o | 21 | //kbuild:lib-$(CONFIG_BB_SYSCTL) += sysctl.o |
22 | 22 | ||
23 | //usage:#define sysctl_trivial_usage | 23 | //usage:#define sysctl_trivial_usage |
24 | //usage: "[OPTIONS] [KEY[=VALUE]]..." | 24 | //usage: "-p [-enq] [FILE...] / [-enqaw] [KEY[=VALUE]]..." |
25 | //usage:#define sysctl_full_usage "\n\n" | 25 | //usage:#define sysctl_full_usage "\n\n" |
26 | //usage: "Show/set kernel parameters\n" | 26 | //usage: "Show/set kernel parameters\n" |
27 | //usage: "\n -p Set values from FILEs (default /etc/sysctl.conf)" | ||
27 | //usage: "\n -e Don't warn about unknown keys" | 28 | //usage: "\n -e Don't warn about unknown keys" |
28 | //usage: "\n -n Don't show key names" | 29 | //usage: "\n -n Don't show key names" |
30 | //usage: "\n -q Quiet" | ||
29 | //usage: "\n -a Show all values" | 31 | //usage: "\n -a Show all values" |
30 | /* Same as -a, no need to show it */ | 32 | /* Same as -a, no need to show it */ |
31 | /* //usage: "\n -A Show all values in table form" */ | 33 | /* //usage: "\n -A Show all values in table form" */ |
32 | //usage: "\n -w Set values" | 34 | //usage: "\n -w Set values" |
33 | //usage: "\n -p FILE Set values from FILE (default /etc/sysctl.conf)" | ||
34 | //usage: "\n -q Set values silently" | ||
35 | //usage: | 35 | //usage: |
36 | //usage:#define sysctl_example_usage | 36 | //usage:#define sysctl_example_usage |
37 | //usage: "sysctl [-n] [-e] variable...\n" | 37 | //usage: "sysctl [-n] [-e] variable...\n" |
@@ -48,7 +48,7 @@ enum { | |||
48 | FLAG_TABLE_FORMAT = 1 << 2, /* not implemented */ | 48 | FLAG_TABLE_FORMAT = 1 << 2, /* not implemented */ |
49 | FLAG_SHOW_ALL = 1 << 3, | 49 | FLAG_SHOW_ALL = 1 << 3, |
50 | FLAG_PRELOAD_FILE = 1 << 4, | 50 | FLAG_PRELOAD_FILE = 1 << 4, |
51 | /* TODO: procps 3.2.8 seems to not require -w for KEY=VAL to work: */ | 51 | /* NB: procps 3.2.8 does not require -w for KEY=VAL to work, it only rejects non-KEY=VAL form */ |
52 | FLAG_WRITE = 1 << 5, | 52 | FLAG_WRITE = 1 << 5, |
53 | FLAG_QUIET = 1 << 6, | 53 | FLAG_QUIET = 1 << 6, |
54 | }; | 54 | }; |
@@ -104,6 +104,7 @@ static int sysctl_act_on_setting(char *setting) | |||
104 | int fd, retval = EXIT_SUCCESS; | 104 | int fd, retval = EXIT_SUCCESS; |
105 | char *cptr, *outname; | 105 | char *cptr, *outname; |
106 | char *value = value; /* for compiler */ | 106 | char *value = value; /* for compiler */ |
107 | bool writing = (option_mask32 & FLAG_WRITE); | ||
107 | 108 | ||
108 | outname = xstrdup(setting); | 109 | outname = xstrdup(setting); |
109 | 110 | ||
@@ -114,8 +115,10 @@ static int sysctl_act_on_setting(char *setting) | |||
114 | cptr++; | 115 | cptr++; |
115 | } | 116 | } |
116 | 117 | ||
117 | if (option_mask32 & FLAG_WRITE) { | 118 | cptr = strchr(setting, '='); |
118 | cptr = strchr(setting, '='); | 119 | if (cptr) |
120 | writing = 1; | ||
121 | if (writing) { | ||
119 | if (cptr == NULL) { | 122 | if (cptr == NULL) { |
120 | bb_error_msg("error: '%s' must be of the form name=value", | 123 | bb_error_msg("error: '%s' must be of the form name=value", |
121 | outname); | 124 | outname); |
@@ -147,7 +150,7 @@ static int sysctl_act_on_setting(char *setting) | |||
147 | break; | 150 | break; |
148 | default: | 151 | default: |
149 | bb_perror_msg("error %sing key '%s'", | 152 | bb_perror_msg("error %sing key '%s'", |
150 | option_mask32 & FLAG_WRITE ? | 153 | writing ? |
151 | "sett" : "read", | 154 | "sett" : "read", |
152 | outname); | 155 | outname); |
153 | break; | 156 | break; |
@@ -156,7 +159,7 @@ static int sysctl_act_on_setting(char *setting) | |||
156 | goto end; | 159 | goto end; |
157 | } | 160 | } |
158 | 161 | ||
159 | if (option_mask32 & FLAG_WRITE) { | 162 | if (writing) { |
160 | //TODO: procps 3.2.7 writes "value\n", note trailing "\n" | 163 | //TODO: procps 3.2.7 writes "value\n", note trailing "\n" |
161 | xwrite_str(fd, value); | 164 | xwrite_str(fd, value); |
162 | close(fd); | 165 | close(fd); |
@@ -238,23 +241,33 @@ static int sysctl_handle_preload_file(const char *filename) | |||
238 | { | 241 | { |
239 | char *token[2]; | 242 | char *token[2]; |
240 | parser_t *parser; | 243 | parser_t *parser; |
244 | int parse_flags; | ||
241 | 245 | ||
242 | parser = config_open(filename); | 246 | parser = config_open(filename); |
243 | /* Must do it _after_ config_open(): */ | 247 | /* Must do it _after_ config_open(): */ |
244 | xchdir("/proc/sys"); | 248 | xchdir("/proc/sys"); |
245 | /* xchroot("/proc/sys") - if you are paranoid */ | ||
246 | 249 | ||
247 | //TODO: ';' is comment char too | 250 | parse_flags = 0; |
248 | //TODO: comment may be only at line start. "var=1 #abc" - "1 #abc" is the value | 251 | parse_flags &= ~PARSE_COLLAPSE; // NO (var==val is not var=val) - treat consecutive delimiters as one |
249 | // (but _whitespace_ from ends should be trimmed first (and we do it right)) | 252 | parse_flags &= ~PARSE_TRIM; // NO - trim leading and trailing delimiters |
250 | //TODO: "var==1" is mishandled (must use "=1" as a value, but uses "1") | 253 | parse_flags |= PARSE_GREEDY; // YES - last token takes entire remainder of the line |
251 | // can it be fixed by removing PARSE_COLLAPSE bit? | 254 | parse_flags &= ~PARSE_MIN_DIE; // NO - die if < min tokens found |
252 | while (config_read(parser, token, 2, 2, "# \t=", PARSE_NORMAL)) { | 255 | parse_flags &= ~PARSE_EOL_COMMENTS; // NO (only first char) - comments are recognized even if not first char |
256 | parse_flags |= PARSE_ALT_COMMENTS;// YES - two comment chars: ';' and '#' | ||
257 | /* <space><tab><space>#comment is also comment, not strictly 1st char only */ | ||
258 | parse_flags |= PARSE_WS_COMMENTS; // YES - comments are recognized even if there is whitespace before | ||
259 | while (config_read(parser, token, 2, 2, ";#=", parse_flags)) { | ||
253 | char *tp; | 260 | char *tp; |
261 | |||
262 | trim(token[1]); | ||
263 | tp = trim(token[0]); | ||
254 | sysctl_dots_to_slashes(token[0]); | 264 | sysctl_dots_to_slashes(token[0]); |
255 | tp = xasprintf("%s=%s", token[0], token[1]); | 265 | /* ^^^converted in-place. tp still points to NUL */ |
256 | sysctl_act_recursive(tp); | 266 | /* now, add "=TOKEN1" */ |
257 | free(tp); | 267 | *tp++ = '='; |
268 | overlapping_strcpy(tp, token[1]); | ||
269 | |||
270 | sysctl_act_on_setting(token[0]); | ||
258 | } | 271 | } |
259 | if (ENABLE_FEATURE_CLEAN_UP) | 272 | if (ENABLE_FEATURE_CLEAN_UP) |
260 | config_close(parser); | 273 | config_close(parser); |
@@ -273,12 +286,19 @@ int sysctl_main(int argc UNUSED_PARAM, char **argv) | |||
273 | option_mask32 = opt; | 286 | option_mask32 = opt; |
274 | 287 | ||
275 | if (opt & FLAG_PRELOAD_FILE) { | 288 | if (opt & FLAG_PRELOAD_FILE) { |
289 | int cur_dir_fd; | ||
276 | option_mask32 |= FLAG_WRITE; | 290 | option_mask32 |= FLAG_WRITE; |
277 | /* xchdir("/proc/sys") is inside */ | 291 | if (!*argv) |
278 | return sysctl_handle_preload_file(*argv ? *argv : "/etc/sysctl.conf"); | 292 | *--argv = (char*)"/etc/sysctl.conf"; |
293 | cur_dir_fd = xopen(".", O_RDONLY | O_DIRECTORY); | ||
294 | do { | ||
295 | /* xchdir("/proc/sys") is inside */ | ||
296 | sysctl_handle_preload_file(*argv); | ||
297 | xfchdir(cur_dir_fd); /* files can be relative, must restore cwd */ | ||
298 | } while (*++argv); | ||
299 | return 0; /* procps-ng 3.3.10 does not flag parse errors */ | ||
279 | } | 300 | } |
280 | xchdir("/proc/sys"); | 301 | xchdir("/proc/sys"); |
281 | /* xchroot("/proc/sys") - if you are paranoid */ | ||
282 | if (opt & (FLAG_TABLE_FORMAT | FLAG_SHOW_ALL)) { | 302 | if (opt & (FLAG_TABLE_FORMAT | FLAG_SHOW_ALL)) { |
283 | return sysctl_act_recursive("."); | 303 | return sysctl_act_recursive("."); |
284 | } | 304 | } |
diff --git a/procps/top.c b/procps/top.c index 015d1ab74..f97ded5d6 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -116,7 +116,6 @@ | |||
116 | //kbuild:lib-$(CONFIG_TOP) += top.o | 116 | //kbuild:lib-$(CONFIG_TOP) += top.o |
117 | 117 | ||
118 | #include "libbb.h" | 118 | #include "libbb.h" |
119 | #include "common_bufsiz.h" | ||
120 | 119 | ||
121 | 120 | ||
122 | typedef struct top_status_t { | 121 | typedef struct top_status_t { |
@@ -154,6 +153,8 @@ typedef int (*cmp_funcp)(top_status_t *P, top_status_t *Q); | |||
154 | 153 | ||
155 | enum { SORT_DEPTH = 3 }; | 154 | enum { SORT_DEPTH = 3 }; |
156 | 155 | ||
156 | /* Screens wider than this are unlikely */ | ||
157 | enum { LINE_BUF_SIZE = 512 - 64 }; | ||
157 | 158 | ||
158 | struct globals { | 159 | struct globals { |
159 | top_status_t *top; | 160 | top_status_t *top; |
@@ -192,10 +193,9 @@ struct globals { | |||
192 | #if ENABLE_FEATURE_TOP_INTERACTIVE | 193 | #if ENABLE_FEATURE_TOP_INTERACTIVE |
193 | char kbd_input[KEYCODE_BUFFER_SIZE]; | 194 | char kbd_input[KEYCODE_BUFFER_SIZE]; |
194 | #endif | 195 | #endif |
195 | char line_buf[80]; | 196 | char line_buf[LINE_BUF_SIZE]; |
196 | }; //FIX_ALIASING; - large code growth | 197 | }; |
197 | enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) }; | 198 | #define G (*ptr_to_globals) |
198 | #define G (*(struct globals*)bb_common_bufsiz1) | ||
199 | #define top (G.top ) | 199 | #define top (G.top ) |
200 | #define ntop (G.ntop ) | 200 | #define ntop (G.ntop ) |
201 | #define sort_field (G.sort_field ) | 201 | #define sort_field (G.sort_field ) |
@@ -213,8 +213,7 @@ enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) }; | |||
213 | #define total_pcpu (G.total_pcpu ) | 213 | #define total_pcpu (G.total_pcpu ) |
214 | #define line_buf (G.line_buf ) | 214 | #define line_buf (G.line_buf ) |
215 | #define INIT_G() do { \ | 215 | #define INIT_G() do { \ |
216 | setup_common_bufsiz(); \ | 216 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
217 | BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ | ||
218 | BUILD_BUG_ON(LINE_BUF_SIZE <= 80); \ | 217 | BUILD_BUG_ON(LINE_BUF_SIZE <= 80); \ |
219 | } while (0) | 218 | } while (0) |
220 | 219 | ||
@@ -1110,15 +1109,14 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1110 | #endif | 1109 | #endif |
1111 | 1110 | ||
1112 | /* all args are options; -n NUM */ | 1111 | /* all args are options; -n NUM */ |
1113 | opt_complementary = "-"; /* options can be specified w/o dash */ | 1112 | make_all_argv_opts(argv); /* options can be specified w/o dash */ |
1114 | col = getopt32(argv, "d:n:b"IF_FEATURE_TOPMEM("m"), &str_interval, &str_iterations); | 1113 | col = getopt32(argv, "d:n:b"IF_FEATURE_TOPMEM("m"), &str_interval, &str_iterations); |
1115 | #if ENABLE_FEATURE_TOPMEM | 1114 | #if ENABLE_FEATURE_TOPMEM |
1116 | if (col & OPT_m) /* -m (busybox specific) */ | 1115 | if (col & OPT_m) /* -m (busybox specific) */ |
1117 | scan_mask = TOPMEM_MASK; | 1116 | scan_mask = TOPMEM_MASK; |
1118 | #endif | 1117 | #endif |
1119 | if (col & OPT_d) { | 1118 | if (col & OPT_d) { |
1120 | /* work around for "-d 1" -> "-d -1" done by getopt32 | 1119 | /* work around for "-d 1" -> "-d -1" done by make_all_argv_opts() */ |
1121 | * (opt_complementary == "-" does this) */ | ||
1122 | if (str_interval[0] == '-') | 1120 | if (str_interval[0] == '-') |
1123 | str_interval++; | 1121 | str_interval++; |
1124 | /* Need to limit it to not overflow poll timeout */ | 1122 | /* Need to limit it to not overflow poll timeout */ |
@@ -1148,6 +1146,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1148 | else { | 1146 | else { |
1149 | /* Turn on unbuffered input; turn off echoing, ^C ^Z etc */ | 1147 | /* Turn on unbuffered input; turn off echoing, ^C ^Z etc */ |
1150 | set_termios_to_raw(STDIN_FILENO, &initial_settings, TERMIOS_CLEAR_ISIG); | 1148 | set_termios_to_raw(STDIN_FILENO, &initial_settings, TERMIOS_CLEAR_ISIG); |
1149 | die_func = reset_term; | ||
1151 | } | 1150 | } |
1152 | 1151 | ||
1153 | bb_signals(BB_FATAL_SIGS, sig_catcher); | 1152 | bb_signals(BB_FATAL_SIGS, sig_catcher); |
diff --git a/procps/uptime.c b/procps/uptime.c index 24b2b39df..b0ee8391b 100644 --- a/procps/uptime.c +++ b/procps/uptime.c | |||
@@ -27,7 +27,7 @@ | |||
27 | //config: help | 27 | //config: help |
28 | //config: Display the number of users currently logged on. | 28 | //config: Display the number of users currently logged on. |
29 | 29 | ||
30 | //applet:IF_UPTIME(APPLET(uptime, BB_DIR_USR_BIN, BB_SUID_DROP)) | 30 | //applet:IF_UPTIME(APPLET_NOEXEC(uptime, uptime, BB_DIR_USR_BIN, BB_SUID_DROP, uptime)) |
31 | 31 | ||
32 | //kbuild:lib-$(CONFIG_UPTIME) += uptime.o | 32 | //kbuild:lib-$(CONFIG_UPTIME) += uptime.o |
33 | 33 | ||
diff --git a/procps/watch.c b/procps/watch.c index 2bb7cca90..6fc9f7db7 100644 --- a/procps/watch.c +++ b/procps/watch.c | |||
@@ -62,9 +62,9 @@ int watch_main(int argc UNUSED_PARAM, char **argv) | |||
62 | xopen("/dev/null", O_RDONLY); | 62 | xopen("/dev/null", O_RDONLY); |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | opt_complementary = "-1"; // at least one param; -n NUM | 65 | // "+": stop at first non-option (procps 3.x only); -n NUM |
66 | // "+": stop at first non-option (procps 3.x only) | 66 | // at least one param |
67 | opt = getopt32(argv, "+dtn:+", &period); | 67 | opt = getopt32(argv, "^+" "dtn:+" "\0" "-1", &period); |
68 | argv += optind; | 68 | argv += optind; |
69 | 69 | ||
70 | // watch from both procps 2.x and 3.x does concatenation. Example: | 70 | // watch from both procps 2.x and 3.x does concatenation. Example: |