aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-03-17 09:29:43 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-03-17 09:29:43 +0000
commitb44c790e41e281965955a83408f35ea53ecdb3d2 (patch)
tree98514dba64f7b74b9d60882bfeca1e2c4976b033
parentd25c33f186c7cf3618c34ce79af94fe156f9ab02 (diff)
downloadbusybox-w32-b44c790e41e281965955a83408f35ea53ecdb3d2.tar.gz
busybox-w32-b44c790e41e281965955a83408f35ea53ecdb3d2.tar.bz2
busybox-w32-b44c790e41e281965955a83408f35ea53ecdb3d2.zip
*: fix various kinds of damage to letter 'c' in Arkadiusz Mickiewicz' surname.
chrt,taskset,dc,eject: shrink crontab: call "vi" with just name, no path watchdog: intercept all fatal signals function old new delta xstrtoull_range - 35 +35 static.sg_commands - 18 +18 packed_usage 23698 23712 +14 watchdog_main 148 151 +3 crontab_main 637 638 +1 base 1 - -1 static.ps 4 - -4 pointer 4 - -4 stack_machine 99 92 -7 run_command 273 260 -13 eject_main 360 343 -17 static.C 30 12 -18 ptok 61 38 -23 xstrtol_range 27 - -27 get_token 35 - -35 taskset_main 586 550 -36 chrt_main 411 372 -39 dc_main 158 117 -41 time_main 1127 1037 -90 ------------------------------------------------------------------------------ (add/remove: 2/5 grow/shrink: 3/9 up/down: 71/-355) Total: -284 bytes text data bss dec hex filename 793680 662 7420 801762 c3be2 busybox_old 793327 662 7412 801401 c3a79 busybox_unstripped
-rw-r--r--docs/ctty.htm4
-rw-r--r--include/libbb.h4
-rw-r--r--include/usage.h2
-rw-r--r--loginutils/getty.c5
-rw-r--r--miscutils/chrt.c92
-rw-r--r--miscutils/crond.c4
-rw-r--r--miscutils/crontab.c11
-rw-r--r--miscutils/dc.c94
-rw-r--r--miscutils/eject.c95
-rw-r--r--miscutils/last.c2
-rw-r--r--miscutils/setsid.c10
-rw-r--r--miscutils/taskset.c88
-rw-r--r--miscutils/time.c118
-rw-r--r--miscutils/ttysize.c2
-rw-r--r--miscutils/watchdog.c16
-rw-r--r--util-linux/fsck_minix.c2
-rw-r--r--util-linux/getopt.c2
-rw-r--r--util-linux/mount.c2
18 files changed, 269 insertions, 284 deletions
diff --git a/docs/ctty.htm b/docs/ctty.htm
index b8bce003c..8f466cdde 100644
--- a/docs/ctty.htm
+++ b/docs/ctty.htm
@@ -145,7 +145,7 @@ PID (process ID), PGID (process group ID) and SID (session ID)
145of processes. With a shell that does not know about job control, 145of processes. With a shell that does not know about job control,
146like <code>ash</code>, each of its children will be in the same session 146like <code>ash</code>, each of its children will be in the same session
147and have the same process group as the shell. With a shell that knows 147and have the same process group as the shell. With a shell that knows
148about job control, like <code>bash</code>, the processes of one pipeline. like 148about job control, like <code>bash</code>, the processes of one pipeline, like
149</p><blockquote> 149</p><blockquote>
150<pre>% cat paper | ideal | pic | tbl | eqn | ditroff &gt; out 150<pre>% cat paper | ideal | pic | tbl | eqn | ditroff &gt; out
151</pre> 151</pre>
@@ -227,7 +227,7 @@ controlling tty. If there is none, this returns a random value
227larger than 1 that is not a process group ID. 227larger than 1 that is not a process group ID.
228</p><p>A process can set the foreground process group in its session 228</p><p>A process can set the foreground process group in its session
229using <code>tcsetpgrp(fd,pgrp)</code>, where <code>fd</code> refers to its 229using <code>tcsetpgrp(fd,pgrp)</code>, where <code>fd</code> refers to its
230controlling tty, and <code>pgrp</code> is a process group in the 230controlling tty, and <code>pgrp</code> is a process group in
231its session, and this session still is associated to the controlling 231its session, and this session still is associated to the controlling
232tty of the calling process. 232tty of the calling process.
233</p><p>How does one get <code>fd</code>? By definition, <code>/dev/tty</code> 233</p><p>How does one get <code>fd</code>? By definition, <code>/dev/tty</code>
diff --git a/include/libbb.h b/include/libbb.h
index 99d681dbe..654643743 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -707,7 +707,7 @@ int run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char **
707 * 707 *
708 * forkexit_or_rexec(argv) = bare-bones "fork + parent exits" on MMU, 708 * forkexit_or_rexec(argv) = bare-bones "fork + parent exits" on MMU,
709 * "vfork + re-exec ourself" on NOMMU. No fd redirection, no setsid(). 709 * "vfork + re-exec ourself" on NOMMU. No fd redirection, no setsid().
710 * Currently used for openvt. On MMU ignores argv. 710 * Currently used for openvt and setsid. On MMU ignores argv.
711 * 711 *
712 * Helper for network daemons in foreground mode: 712 * Helper for network daemons in foreground mode:
713 * 713 *
@@ -728,7 +728,7 @@ enum {
728# define bb_daemonize(flags) bb_daemonize_or_rexec(flags, bogus) 728# define bb_daemonize(flags) bb_daemonize_or_rexec(flags, bogus)
729#else 729#else
730 void re_exec(char **argv) ATTRIBUTE_NORETURN; 730 void re_exec(char **argv) ATTRIBUTE_NORETURN;
731 void forkexit_or_rexec(char **argv); 731 void forkexit_or_rexec(char **argv) ATTRIBUTE_NORETURN;
732 extern bool re_execed; 732 extern bool re_execed;
733 int BUG_fork_is_unavailable_on_nommu(void); 733 int BUG_fork_is_unavailable_on_nommu(void);
734 int BUG_daemon_is_unavailable_on_nommu(void); 734 int BUG_daemon_is_unavailable_on_nommu(void);
diff --git a/include/usage.h b/include/usage.h
index 8f563f55e..fe98398ab 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -3839,7 +3839,7 @@
3839 "$ tar -cf /tmp/tarball.tar /usr/local\n" 3839 "$ tar -cf /tmp/tarball.tar /usr/local\n"
3840 3840
3841#define taskset_trivial_usage \ 3841#define taskset_trivial_usage \
3842 "[OPTIONS] [mask] [pid | command [arg]...]" 3842 "[-p] [mask] [pid | command [arg]...]"
3843#define taskset_full_usage \ 3843#define taskset_full_usage \
3844 "Set or get CPU affinity\n" \ 3844 "Set or get CPU affinity\n" \
3845 "\nOptions:" \ 3845 "\nOptions:" \
diff --git a/loginutils/getty.c b/loginutils/getty.c
index c8c54e3b9..da0dce391 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -6,14 +6,13 @@
6 * 6 *
7 * option added by Eric Rasmussen <ear@usfirst.org> - 12/28/95 7 * option added by Eric Rasmussen <ear@usfirst.org> - 12/28/95
8 * 8 *
9 * 1999-02-22 Arkadiusz Mikiewicz <misiek@misiek.eu.org> 9 * 1999-02-22 Arkadiusz Mickiewicz <misiek@misiek.eu.org>
10 * - added Native Language Support 10 * - added Native Language Support
11 11 *
12 * 1999-05-05 Thorsten Kranzkowski <dl8bcu@gmx.net> 12 * 1999-05-05 Thorsten Kranzkowski <dl8bcu@gmx.net>
13 * - enable hardware flow control before displaying /etc/issue 13 * - enable hardware flow control before displaying /etc/issue
14 * 14 *
15 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 15 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
16 *
17 */ 16 */
18 17
19#include "libbb.h" 18#include "libbb.h"
diff --git a/miscutils/chrt.c b/miscutils/chrt.c
index 418e7ae79..0d55e3299 100644
--- a/miscutils/chrt.c
+++ b/miscutils/chrt.c
@@ -13,8 +13,8 @@
13#warning your system may be foobared 13#warning your system may be foobared
14#endif 14#endif
15static const struct { 15static const struct {
16 const int policy; 16 int policy;
17 const char const name[12]; 17 char name[12];
18} policies[] = { 18} policies[] = {
19 {SCHED_OTHER, "SCHED_OTHER"}, 19 {SCHED_OTHER, "SCHED_OTHER"},
20 {SCHED_FIFO, "SCHED_FIFO"}, 20 {SCHED_FIFO, "SCHED_FIFO"},
@@ -42,83 +42,83 @@ static void show_min_max(int pol)
42#define OPT_o (1<<4) 42#define OPT_o (1<<4)
43 43
44int chrt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 44int chrt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
45int chrt_main(int argc, char **argv) 45int chrt_main(int argc ATTRIBUTE_UNUSED, char **argv)
46{ 46{
47 pid_t pid = 0; 47 pid_t pid = 0;
48 unsigned opt; 48 unsigned opt;
49 struct sched_param sp; 49 struct sched_param sp;
50 char *p_opt = NULL, *priority = NULL; 50 char *pid_str;
51 const char *state = "current\0new"; 51 char *priority = priority; /* for compiler */
52 int prio = 0, policy = SCHED_RR; 52 const char *current_new;
53 int policy = SCHED_RR;
53 54
54 opt_complementary = "r--fo:f--ro:r--fo"; /* only one policy accepted */ 55 /* at least 1 arg; only one policy accepted */
55 opt = getopt32(argv, "+mp:rfo", &p_opt); 56 opt_complementary = "-1:r--fo:f--ro:r--fo";
57 opt = getopt32(argv, "+mprfo");
56 if (opt & OPT_r) 58 if (opt & OPT_r)
57 policy = SCHED_RR; 59 policy = SCHED_RR;
58 if (opt & OPT_f) 60 if (opt & OPT_f)
59 policy = SCHED_FIFO; 61 policy = SCHED_FIFO;
60 if (opt & OPT_o) 62 if (opt & OPT_o)
61 policy = SCHED_OTHER; 63 policy = SCHED_OTHER;
62
63 if (opt & OPT_m) { /* print min/max */ 64 if (opt & OPT_m) { /* print min/max */
64 show_min_max(SCHED_FIFO); 65 show_min_max(SCHED_FIFO);
65 show_min_max(SCHED_RR); 66 show_min_max(SCHED_RR);
66 show_min_max(SCHED_OTHER); 67 show_min_max(SCHED_OTHER);
67 fflush_stdout_and_exit(EXIT_SUCCESS); 68 fflush_stdout_and_exit(EXIT_SUCCESS);
68 } 69 }
70
71 argv += optind;
69 if (opt & OPT_p) { 72 if (opt & OPT_p) {
70 if (argc == optind+1) { /* -p <priority> <pid> */ 73 pid_str = *argv++;
71 priority = p_opt; 74 if (*argv) { /* "-p <priority> <pid> [...]" */
72 p_opt = argv[optind]; 75 priority = pid_str;
76 pid_str = *argv;
73 } 77 }
74 argv += optind; /* me -p <arg> */ 78 /* else "-p <pid>", and *argv == NULL */
75 pid = xatoul_range(p_opt, 1, ULONG_MAX); /* -p <pid> */ 79 pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1);
76 } else { 80 } else {
77 argv += optind; /* me -p <arg> */ 81 priority = *argv++;
78 priority = *argv; 82 if (!*argv)
79 } 83 bb_show_usage();
80 if (priority) {
81 /* from the manpage of sched_getscheduler:
82 [...] sched_priority can have a value
83 in the range 0 to 99.
84 [...] SCHED_OTHER or SCHED_BATCH must be assigned
85 the static priority 0. [...] SCHED_FIFO or
86 SCHED_RR can have a static priority in the range 1 to 99.
87 */
88 prio = xstrtol_range(priority, 0, policy == SCHED_OTHER
89 ? 0 : 1, 99);
90 } 84 }
91 85
86 current_new = "current\0new";
92 if (opt & OPT_p) { 87 if (opt & OPT_p) {
93 int pol = 0; 88 int pol;
94print_rt_info: 89 print_rt_info:
95 pol = sched_getscheduler(pid); 90 pol = sched_getscheduler(pid);
96 if (pol < 0) 91 if (pol < 0)
97 bb_perror_msg_and_die("failed to %cet pid %d's policy", 'g', pid); 92 bb_perror_msg_and_die("can't %cet pid %d's policy", 'g', pid);
98 printf("pid %d's %s scheduling policy: %s\n", 93 printf("pid %d's %s scheduling policy: %s\n",
99 pid, state, policies[pol].name); 94 pid, current_new, policies[pol].name);
100 if (sched_getparam(pid, &sp)) 95 if (sched_getparam(pid, &sp))
101 bb_perror_msg_and_die("failed to get pid %d's attributes", pid); 96 bb_perror_msg_and_die("can't get pid %d's attributes", pid);
102 printf("pid %d's %s scheduling priority: %d\n", 97 printf("pid %d's %s scheduling priority: %d\n",
103 pid, state, sp.sched_priority); 98 pid, current_new, sp.sched_priority);
104 if (!*argv) /* no new prio given or we did print already, done. */ 99 if (!*argv) {
100 /* Either it was just "-p <pid>",
101 * or it was "-p <priority> <pid>" and we came here
102 * for the second time (see goto below) */
105 return EXIT_SUCCESS; 103 return EXIT_SUCCESS;
104 }
105 *argv = NULL;
106 current_new += 8;
106 } 107 }
107 108
108 sp.sched_priority = prio; 109 /* from the manpage of sched_getscheduler:
110 [...] sched_priority can have a value in the range 0 to 99.
111 [...] SCHED_OTHER or SCHED_BATCH must be assigned static priority 0.
112 [...] SCHED_FIFO or SCHED_RR can have static priority in 1..99 range.
113 */
114 sp.sched_priority = xstrtou_range(priority, 0, policy != SCHED_OTHER ? 1 : 0, 99);
115
109 if (sched_setscheduler(pid, policy, &sp) < 0) 116 if (sched_setscheduler(pid, policy, &sp) < 0)
110 bb_perror_msg_and_die("failed to %cet pid %d's policy", 's', pid); 117 bb_perror_msg_and_die("can't %cet pid %d's policy", 's', pid);
111 if (opt & OPT_p) { 118
112 state += 8; 119 if (!*argv) /* "-p <priority> <pid> [...]" */
113 ++argv;
114 goto print_rt_info; 120 goto print_rt_info;
115 } 121
116 ++argv;
117 BB_EXECVP(*argv, argv); 122 BB_EXECVP(*argv, argv);
118 bb_simple_perror_msg_and_die(*argv); 123 bb_simple_perror_msg_and_die(*argv);
119} 124}
120#undef OPT_p
121#undef OPT_r
122#undef OPT_f
123#undef OPT_o
124#undef OPT_m
diff --git a/miscutils/crond.c b/miscutils/crond.c
index 75555c874..fcfc120f0 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -158,7 +158,7 @@ static void crondlog(const char *ctl, ...)
158} 158}
159 159
160int crond_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 160int crond_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
161int crond_main(int ac ATTRIBUTE_UNUSED, char **av) 161int crond_main(int argc ATTRIBUTE_UNUSED, char **argv)
162{ 162{
163 unsigned opt; 163 unsigned opt;
164 164
@@ -167,7 +167,7 @@ int crond_main(int ac ATTRIBUTE_UNUSED, char **av)
167 /* "-b after -f is ignored", and so on for every pair a-b */ 167 /* "-b after -f is ignored", and so on for every pair a-b */
168 opt_complementary = "f-b:b-f:S-L:L-S" USE_DEBUG_CROND_OPTION(":d-l") 168 opt_complementary = "f-b:b-f:S-L:L-S" USE_DEBUG_CROND_OPTION(":d-l")
169 ":l+:d+"; /* -l and -d have numeric param */ 169 ":l+:d+"; /* -l and -d have numeric param */
170 opt = getopt32(av, "l:L:fbSc:" USE_DEBUG_CROND_OPTION("d:"), 170 opt = getopt32(argv, "l:L:fbSc:" USE_DEBUG_CROND_OPTION("d:"),
171 &LogLevel, &LogFile, &CDir 171 &LogLevel, &LogFile, &CDir
172 USE_DEBUG_CROND_OPTION(,&LogLevel)); 172 USE_DEBUG_CROND_OPTION(,&LogLevel));
173 /* both -d N and -l N set the same variable: LogLevel */ 173 /* both -d N and -l N set the same variable: LogLevel */
diff --git a/miscutils/crontab.c b/miscutils/crontab.c
index 94d69f032..dc3179dac 100644
--- a/miscutils/crontab.c
+++ b/miscutils/crontab.c
@@ -18,9 +18,6 @@
18#ifndef CRONUPDATE 18#ifndef CRONUPDATE
19#define CRONUPDATE "cron.update" 19#define CRONUPDATE "cron.update"
20#endif 20#endif
21#ifndef PATH_VI
22#define PATH_VI "/bin/vi" /* location of vi */
23#endif
24 21
25static void change_user(const struct passwd *pas) 22static void change_user(const struct passwd *pas)
26{ 23{
@@ -56,7 +53,7 @@ static void edit_file(const struct passwd *pas, const char *file)
56 if (!ptr) { 53 if (!ptr) {
57 ptr = getenv("EDITOR"); 54 ptr = getenv("EDITOR");
58 if (!ptr) 55 if (!ptr)
59 ptr = PATH_VI; 56 ptr = "vi";
60 } 57 }
61 58
62 BB_EXECLP(ptr, ptr, file, NULL); 59 BB_EXECLP(ptr, ptr, file, NULL);
@@ -181,14 +178,16 @@ int crontab_main(int argc ATTRIBUTE_UNUSED, char **argv)
181 178
182 case OPT_e: /* Edit */ 179 case OPT_e: /* Edit */
183 tmp_fname = xasprintf("%s.%u", crontab_dir, (unsigned)getpid()); 180 tmp_fname = xasprintf("%s.%u", crontab_dir, (unsigned)getpid());
184 fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0600); 181 /* No O_EXCL: we don't want to be stuck if earlier crontabs
182 * were killed, leaving stale temp file behind */
183 fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC, 0600);
185 xmove_fd(fd, STDIN_FILENO); 184 xmove_fd(fd, STDIN_FILENO);
185 fchown(STDIN_FILENO, pas->pw_uid, pas->pw_gid);
186 fd = open(pas->pw_name, O_RDONLY); 186 fd = open(pas->pw_name, O_RDONLY);
187 if (fd >= 0) { 187 if (fd >= 0) {
188 bb_copyfd_eof(fd, STDIN_FILENO); 188 bb_copyfd_eof(fd, STDIN_FILENO);
189 close(fd); 189 close(fd);
190 } 190 }
191 fchown(STDIN_FILENO, pas->pw_uid, pas->pw_gid);
192 edit_file(pas, tmp_fname); 191 edit_file(pas, tmp_fname);
193 xlseek(STDIN_FILENO, 0, SEEK_SET); 192 xlseek(STDIN_FILENO, 0, SEEK_SET);
194 /* fall through */ 193 /* fall through */
diff --git a/miscutils/dc.c b/miscutils/dc.c
index ffc3f8df4..68ecd8a3f 100644
--- a/miscutils/dc.c
+++ b/miscutils/dc.c
@@ -8,11 +8,18 @@
8 8
9/* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ 9/* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */
10 10
11enum { STACK_SIZE = COMMON_BUFSIZE / sizeof(double) };
12 11
13#define stack ((double*)&bb_common_bufsiz1) 12struct globals {
14static unsigned int pointer; 13 unsigned pointer;
15static unsigned char base; 14 unsigned base;
15 double stack[1];
16};
17enum { STACK_SIZE = (COMMON_BUFSIZE - offsetof(struct globals, stack)) / sizeof(double) };
18#define G (*(struct globals*)&bb_common_bufsiz1)
19#define pointer (G.pointer )
20#define base (G.base )
21#define stack (G.stack )
22
16 23
17static void push(double a) 24static void push(double a)
18{ 25{
@@ -61,34 +68,34 @@ static void divide(void)
61 68
62static void mod(void) 69static void mod(void)
63{ 70{
64 unsigned int d = pop(); 71 unsigned d = pop();
65 72
66 push((unsigned int) pop() % d); 73 push((unsigned) pop() % d);
67} 74}
68 75
69static void and(void) 76static void and(void)
70{ 77{
71 push((unsigned int) pop() & (unsigned int) pop()); 78 push((unsigned) pop() & (unsigned) pop());
72} 79}
73 80
74static void or(void) 81static void or(void)
75{ 82{
76 push((unsigned int) pop() | (unsigned int) pop()); 83 push((unsigned) pop() | (unsigned) pop());
77} 84}
78 85
79static void eor(void) 86static void eor(void)
80{ 87{
81 push((unsigned int) pop() ^ (unsigned int) pop()); 88 push((unsigned) pop() ^ (unsigned) pop());
82} 89}
83 90
84static void not(void) 91static void not(void)
85{ 92{
86 push(~(unsigned int) pop()); 93 push(~(unsigned) pop());
87} 94}
88 95
89static void set_output_base(void) 96static void set_output_base(void)
90{ 97{
91 base = (unsigned char)pop(); 98 base = (unsigned)pop();
92 if ((base != 10) && (base != 16)) { 99 if ((base != 10) && (base != 16)) {
93 bb_error_msg("error, base %d is not supported", base); 100 bb_error_msg("error, base %d is not supported", base);
94 base = 10; 101 base = 10;
@@ -98,14 +105,14 @@ static void set_output_base(void)
98static void print_base(double print) 105static void print_base(double print)
99{ 106{
100 if (base == 16) 107 if (base == 16)
101 printf("%x\n", (unsigned int)print); 108 printf("%x\n", (unsigned)print);
102 else 109 else
103 printf("%g\n", print); 110 printf("%g\n", print);
104} 111}
105 112
106static void print_stack_no_pop(void) 113static void print_stack_no_pop(void)
107{ 114{
108 unsigned int i = pointer; 115 unsigned i = pointer;
109 while (i) 116 while (i)
110 print_base(stack[--i]); 117 print_base(stack[--i]);
111} 118}
@@ -142,12 +149,12 @@ static const struct op operators[] = {
142 {"p", print_no_pop}, 149 {"p", print_no_pop},
143 {"f", print_stack_no_pop}, 150 {"f", print_stack_no_pop},
144 {"o", set_output_base}, 151 {"o", set_output_base},
145 {"", 0} 152 { /* zero filled */ }
146}; 153};
147 154
148static void stack_machine(const char *argument) 155static void stack_machine(const char *argument)
149{ 156{
150 char *endPointer = 0; 157 char *endPointer;
151 double d; 158 double d;
152 const struct op *o = operators; 159 const struct op *o = operators;
153 160
@@ -176,54 +183,39 @@ static void stack_machine(const char *argument)
176 */ 183 */
177static char *get_token(char **buffer) 184static char *get_token(char **buffer)
178{ 185{
179 char *start = NULL; 186 char *current = skip_whitespace(*buffer);
180 char *current; 187 if (*current != '\0') {
181 188 *buffer = skip_non_whitespace(current);
182 current = skip_whitespace(*buffer); 189 return current;
183 if (*current != 0) {
184 start = current;
185 current = skip_non_whitespace(current);
186 *buffer = current;
187 } 190 }
188 return start; 191 return NULL;
189}
190
191/* In Perl one might say, scalar m|\s*(\S+)\s*|g */
192static int number_of_tokens(char *buffer)
193{
194 int i = 0;
195 char *b = buffer;
196 while (get_token(&b)) { i++; }
197 return i;
198} 192}
199 193
200int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 194int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
201int dc_main(int argc, char **argv) 195int dc_main(int argc ATTRIBUTE_UNUSED, char **argv)
202{ 196{
203 /* take stuff from stdin if no args are given */ 197 argv++;
204 if (argc <= 1) { 198 if (!argv[0]) {
205 int i, len; 199 /* take stuff from stdin if no args are given */
206 char *line = NULL; 200 char *line;
207 char *cursor = NULL; 201 char *cursor;
208 char *token = NULL; 202 char *token;
209 while ((line = xmalloc_getline(stdin))) { 203 while ((line = xmalloc_getline(stdin)) != NULL) {
210 cursor = line; 204 cursor = line;
211 len = number_of_tokens(line); 205 while (1) {
212 for (i = 0; i < len; i++) {
213 token = get_token(&cursor); 206 token = get_token(&cursor);
214 *cursor++ = 0; 207 if (!token) break;
208 *cursor++ = '\0';
215 stack_machine(token); 209 stack_machine(token);
216 } 210 }
217 free(line); 211 free(line);
218 } 212 }
219 } else { 213 } else {
220 if (*argv[1] == '-') 214 if (argv[0][0] == '-')
221 bb_show_usage(); 215 bb_show_usage();
222 while (argc >= 2) { 216 do {
223 stack_machine(argv[1]); 217 stack_machine(*argv);
224 argv++; 218 } while (*++argv);
225 argc--;
226 }
227 } 219 }
228 return EXIT_SUCCESS; 220 return EXIT_SUCCESS;
229} 221}
diff --git a/miscutils/eject.c b/miscutils/eject.c
index 3d27ce545..42e071941 100644
--- a/miscutils/eject.c
+++ b/miscutils/eject.c
@@ -22,68 +22,71 @@
22/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ 22/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
23#define CDS_TRAY_OPEN 2 23#define CDS_TRAY_OPEN 2
24 24
25#define FLAG_CLOSE 1 25#define dev_fd 3
26#define FLAG_SMART 2
27
28 26
29/* Code taken from the original eject (http://eject.sourceforge.net/), 27/* Code taken from the original eject (http://eject.sourceforge.net/),
30 * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */ 28 * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */
31#define FLAG_SCSI 4
32 29
33#include <scsi/sg.h> 30#include <scsi/sg.h>
34#include <scsi/scsi.h> 31#include <scsi/scsi.h>
35static void eject_scsi(const int fd, const char * const dev) 32
33static void eject_scsi(const char *dev)
36{ 34{
37 int i; 35 static const char sg_commands[3][6] = {
38 unsigned char sense_buffer[32]; 36 { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 },
39 unsigned char inqBuff[2]; 37 { START_STOP, 0, 0, 0, 1, 0 },
40 sg_io_hdr_t io_hdr; 38 { START_STOP, 0, 0, 0, 2, 0 }
41 char sg_commands[3][6] = { 39 };
42 {ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0}, 40
43 {START_STOP, 0, 0, 0, 1, 0}, 41 int i;
44 {START_STOP, 0, 0, 0, 2, 0} 42 unsigned char sense_buffer[32];
45 }; 43 unsigned char inqBuff[2];
46 44 sg_io_hdr_t io_hdr;
47 if ((ioctl(fd, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000)) 45
48 bb_error_msg_and_die("not an sg device or old sg driver"); 46 if ((ioctl(dev_fd, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000))
49 47 bb_error_msg_and_die("not a sg device or old sg driver");
50 memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); 48
51 io_hdr.interface_id = 'S'; 49 memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
52 io_hdr.cmd_len = 6; 50 io_hdr.interface_id = 'S';
53 io_hdr.mx_sb_len = sizeof(sense_buffer); 51 io_hdr.cmd_len = 6;
54 io_hdr.dxfer_direction = SG_DXFER_NONE; 52 io_hdr.mx_sb_len = sizeof(sense_buffer);
55 /* io_hdr.dxfer_len = 0; */ 53 io_hdr.dxfer_direction = SG_DXFER_NONE;
56 io_hdr.dxferp = inqBuff; 54 /* io_hdr.dxfer_len = 0; */
57 io_hdr.sbp = sense_buffer; 55 io_hdr.dxferp = inqBuff;
58 io_hdr.timeout = 2000; 56 io_hdr.sbp = sense_buffer;
59 57 io_hdr.timeout = 2000;
60 for (i=0; i < 3; i++) { 58
61 io_hdr.cmdp = sg_commands[i]; 59 for (i = 0; i < 3; i++) {
62 ioctl_or_perror_and_die(fd, SG_IO, (void *)&io_hdr, "%s", dev); 60 io_hdr.cmdp = (char*)sg_commands[i];
63 } 61 ioctl_or_perror_and_die(dev_fd, SG_IO, (void *)&io_hdr, "%s", dev);
64 62 }
65 /* force kernel to reread partition table when new disc inserted */ 63
66 ioctl(fd, BLKRRPART); 64 /* force kernel to reread partition table when new disc is inserted */
65 ioctl(dev_fd, BLKRRPART);
67} 66}
68 67
69static void eject_cdrom(const int fd, const unsigned long flags, 68#define FLAG_CLOSE 1
70 const char * const dev) 69#define FLAG_SMART 2
70#define FLAG_SCSI 4
71
72static void eject_cdrom(unsigned flags, const char *dev)
71{ 73{
72 int cmd = CDROMEJECT; 74 int cmd = CDROMEJECT;
73 75
74 if (flags & FLAG_CLOSE 76 if (flags & FLAG_CLOSE
75 || (flags & FLAG_SMART && ioctl(fd, CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN)) 77 || (flags & FLAG_SMART && ioctl(dev_fd, CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN)
78 ) {
76 cmd = CDROMCLOSETRAY; 79 cmd = CDROMCLOSETRAY;
80 }
77 81
78 return ioctl_or_perror_and_die(fd, cmd, NULL, "%s", dev); 82 ioctl_or_perror_and_die(dev_fd, cmd, NULL, "%s", dev);
79} 83}
80 84
81int eject_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 85int eject_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
82int eject_main(int argc ATTRIBUTE_UNUSED, char **argv) 86int eject_main(int argc ATTRIBUTE_UNUSED, char **argv)
83{ 87{
84 unsigned long flags; 88 unsigned flags;
85 const char *device; 89 const char *device;
86 int dev;
87 90
88 opt_complementary = "?1:t--T:T--t"; 91 opt_complementary = "?1:t--T:T--t";
89 flags = getopt32(argv, "tT" USE_FEATURE_EJECT_SCSI("s")); 92 flags = getopt32(argv, "tT" USE_FEATURE_EJECT_SCSI("s"));
@@ -96,18 +99,18 @@ int eject_main(int argc ATTRIBUTE_UNUSED, char **argv)
96 This works equally well (or better): 99 This works equally well (or better):
97 #!/bin/sh 100 #!/bin/sh
98 umount /dev/cdrom 101 umount /dev/cdrom
99 eject 102 eject /dev/cdrom
100 */ 103 */
101 104
102 dev = xopen(device, O_RDONLY|O_NONBLOCK); 105 xmove_fd(xopen(device, O_RDONLY|O_NONBLOCK), dev_fd);
103 106
104 if (ENABLE_FEATURE_EJECT_SCSI && (flags & FLAG_SCSI)) 107 if (ENABLE_FEATURE_EJECT_SCSI && (flags & FLAG_SCSI))
105 eject_scsi(dev, device); 108 eject_scsi(device);
106 else 109 else
107 eject_cdrom(dev, flags, device); 110 eject_cdrom(flags, device);
108 111
109 if (ENABLE_FEATURE_CLEAN_UP) 112 if (ENABLE_FEATURE_CLEAN_UP)
110 close(dev); 113 close(dev_fd);
111 114
112 return EXIT_SUCCESS; 115 return EXIT_SUCCESS;
113} 116}
diff --git a/miscutils/last.c b/miscutils/last.c
index f4d9a812e..f46d4ca0c 100644
--- a/miscutils/last.c
+++ b/miscutils/last.c
@@ -14,7 +14,7 @@
14# define SHUTDOWN_TIME 254 14# define SHUTDOWN_TIME 254
15#endif 15#endif
16 16
17/* Grr... utmp char[] members do not have to be nul-terminated. 17/* Grr... utmp char[] members do not have to be nul-terminated.
18 * Do what we can while still keeping this reasonably small. 18 * Do what we can while still keeping this reasonably small.
19 * Note: We are assuming the ut_id[] size is fixed at 4. */ 19 * Note: We are assuming the ut_id[] size is fixed at 4. */
20 20
diff --git a/miscutils/setsid.c b/miscutils/setsid.c
index 110bb6bb6..014de51e5 100644
--- a/miscutils/setsid.c
+++ b/miscutils/setsid.c
@@ -4,7 +4,7 @@
4 * Rick Sladkey <jrs@world.std.com> 4 * Rick Sladkey <jrs@world.std.com>
5 * In the public domain. 5 * In the public domain.
6 * 6 *
7 * 1999-02-22 Arkadiusz Mikiewicz <misiek@pld.ORG.PL> 7 * 1999-02-22 Arkadiusz Mickiewicz <misiek@pld.ORG.PL>
8 * - added Native Language Support 8 * - added Native Language Support
9 * 9 *
10 * 2001-01-18 John Fremlin <vii@penguinpowered.com> 10 * 2001-01-18 John Fremlin <vii@penguinpowered.com>
@@ -17,12 +17,14 @@
17#include "libbb.h" 17#include "libbb.h"
18 18
19int setsid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 19int setsid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
20int setsid_main(int argc, char **argv) 20int setsid_main(int argc ATTRIBUTE_UNUSED, char **argv)
21{ 21{
22 if (argc < 2) 22 if (!argv[1])
23 bb_show_usage(); 23 bb_show_usage();
24 24
25 /* Comment why is this necessary? */ 25 /* setsid() is allowed only when we are not a process group leader.
26 * Otherwise our PID serves as PGID of some existing process group
27 * and cannot be used as PGID of a new process group. */
26 if (getpgrp() == getpid()) 28 if (getpgrp() == getpid())
27 forkexit_or_rexec(argv); 29 forkexit_or_rexec(argv);
28 30
diff --git a/miscutils/taskset.c b/miscutils/taskset.c
index e64fd655b..6247aa869 100644
--- a/miscutils/taskset.c
+++ b/miscutils/taskset.c
@@ -39,61 +39,71 @@ static char *__from_cpuset(cpu_set_t *mask)
39#define from_cpuset(mask) (*(unsigned*)(void*)&(mask)) 39#define from_cpuset(mask) (*(unsigned*)(void*)&(mask))
40#endif 40#endif
41 41
42#define OPT_p 1
43 42
44int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 43int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
45int taskset_main(int argc, char **argv) 44int taskset_main(int argc ATTRIBUTE_UNUSED, char **argv)
46{ 45{
47 cpu_set_t mask, new_mask; 46 cpu_set_t mask;
48 pid_t pid = 0; 47 pid_t pid = 0;
49 unsigned opt; 48 unsigned opt_p;
50 const char *state = "current\0new"; 49 const char *current_new;
51 char *p_opt = NULL, *aff = NULL; 50 char *pid_str;
51 char *aff = aff; /* for compiler */
52 52
53 opt = getopt32(argv, "+p:", &p_opt); 53 opt_complementary = "-1"; /* at least 1 arg */
54 opt_p = getopt32(argv, "+p");
55 argv += optind;
54 56
55 if (opt & OPT_p) { 57 if (opt_p) {
56 if (argc == optind+1) { /* -p <aff> <pid> */ 58 pid_str = *argv++;
57 aff = p_opt; 59 if (*argv) { /* "-p <aff> <pid> ...rest.is.ignored..." */
58 p_opt = argv[optind]; 60 aff = pid_str;
59 } 61 pid_str = *argv; /* NB: *argv != NULL in this case */
60 argv += optind; /* me -p <arg> */
61 pid = xatoul_range(p_opt, 1, ULONG_MAX); /* -p <pid> */
62 } else
63 aff = *++argv; /* <aff> <cmd...> */
64 if (aff) {
65 unsigned i = 0;
66 unsigned long l = xstrtol_range(aff, 0, 1, LONG_MAX);
67
68 CPU_ZERO(&new_mask);
69 while (i < CPU_SETSIZE && l >= (1<<i)) {
70 if ((1<<i) & l)
71 CPU_SET(i, &new_mask);
72 ++i;
73 } 62 }
63 /* else it was just "-p <pid>", and *argv == NULL */
64 pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1);
65 } else {
66 aff = *argv++; /* <aff> <cmd...> */
67 if (!*argv)
68 bb_show_usage();
74 } 69 }
75 70
76 if (opt & OPT_p) { 71 current_new = "current\0new";
72 if (opt_p) {
77 print_aff: 73 print_aff:
78 if (sched_getaffinity(pid, sizeof(mask), &mask) < 0) 74 if (sched_getaffinity(pid, sizeof(mask), &mask) < 0)
79 bb_perror_msg_and_die("failed to %cet pid %d's affinity", 'g', pid); 75 bb_perror_msg_and_die("can't %cet pid %d's affinity", 'g', pid);
80 printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", 76 printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n",
81 pid, state, from_cpuset(mask)); 77 pid, current_new, from_cpuset(mask));
82 if (!*argv) /* no new affinity given or we did print already, done. */ 78 if (!*argv) {
79 /* Either it was just "-p <pid>",
80 * or it was "-p <aff> <pid>" and we came here
81 * for the second time (see goto below) */
83 return EXIT_SUCCESS; 82 return EXIT_SUCCESS;
83 }
84 *argv = NULL;
85 current_new += 8; /* "new" */
84 } 86 }
85 87
86 if (sched_setaffinity(pid, sizeof(new_mask), &new_mask)) 88 { /* Affinity was specified, translate it into cpu_set_t */
87 bb_perror_msg_and_die("failed to %cet pid %d's affinity", 's', pid); 89 unsigned i;
88 if (opt & OPT_p) { 90 /* Do not allow zero mask: */
89 state += 8; 91 unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX);
90 ++argv; 92 CPU_ZERO(&mask);
91 goto print_aff; 93 for (i = 0; i < CPU_SETSIZE; i++) {
94 unsigned long long bit = (1ULL << i);
95 if (bit & m)
96 CPU_SET(i, &mask);
97 }
92 } 98 }
93 ++argv; 99
100 /* Set pid's or our own (pid==0) affinity */
101 if (sched_setaffinity(pid, sizeof(mask), &mask))
102 bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid);
103
104 if (!*argv) /* "-p <aff> <pid> [...ignored...]" */
105 goto print_aff; /* print new affinity and exit */
106
94 BB_EXECVP(*argv, argv); 107 BB_EXECVP(*argv, argv);
95 bb_simple_perror_msg_and_die(*argv); 108 bb_simple_perror_msg_and_die(*argv);
96} 109}
97#undef OPT_p
98#undef TASKSET_PRINTF_MASK
99#undef from_cpuset
diff --git a/miscutils/time.c b/miscutils/time.c
index 677ca6d8b..ed4385948 100644
--- a/miscutils/time.c
+++ b/miscutils/time.c
@@ -1,5 +1,5 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* `time' utility to display resource usage of processes. 2/* 'time' utility to display resource usage of processes.
3 Copyright (C) 1990, 91, 92, 93, 96 Free Software Foundation, Inc. 3 Copyright (C) 1990, 91, 92, 93, 96 Free Software Foundation, Inc.
4 4
5 Licensed under GPL version 2, see file LICENSE in this tarball for details. 5 Licensed under GPL version 2, see file LICENSE in this tarball for details.
@@ -28,7 +28,6 @@ static const char default_format[] ALIGN1 = "real\t%E\nuser\t%u\nsys\t%T";
28/* The output format for the -p option .*/ 28/* The output format for the -p option .*/
29static const char posix_format[] ALIGN1 = "real %e\nuser %U\nsys %S"; 29static const char posix_format[] ALIGN1 = "real %e\nuser %U\nsys %S";
30 30
31
32/* Format string for printing all statistics verbosely. 31/* Format string for printing all statistics verbosely.
33 Keep this output to 24 lines so users on terminals can see it all.*/ 32 Keep this output to 24 lines so users on terminals can see it all.*/
34static const char long_format[] ALIGN1 = 33static const char long_format[] ALIGN1 =
@@ -56,35 +55,31 @@ static const char long_format[] ALIGN1 =
56 "\tPage size (bytes): %Z\n" 55 "\tPage size (bytes): %Z\n"
57 "\tExit status: %x"; 56 "\tExit status: %x";
58 57
59
60/* Wait for and fill in data on child process PID. 58/* Wait for and fill in data on child process PID.
61 Return 0 on error, 1 if ok. */ 59 Return 0 on error, 1 if ok. */
62
63/* pid_t is short on BSDI, so don't try to promote it. */ 60/* pid_t is short on BSDI, so don't try to promote it. */
64static int resuse_end(pid_t pid, resource_t *resp) 61static void resuse_end(pid_t pid, resource_t *resp)
65{ 62{
66 int status;
67 pid_t caught; 63 pid_t caught;
68 64
69 /* Ignore signals, but don't ignore the children. When wait3 65 /* Ignore signals, but don't ignore the children. When wait3
70 returns the child process, set the time the command finished. */ 66 returns the child process, set the time the command finished. */
71 while ((caught = wait3(&status, 0, &resp->ru)) != pid) { 67 while ((caught = wait3(&resp->waitstatus, 0, &resp->ru)) != pid) {
72 if (caught == -1 && errno != EINTR) 68 if (caught == -1 && errno != EINTR) {
73 return 0; 69 bb_perror_msg("wait");
70 return;
71 }
74 } 72 }
75 resp->elapsed_ms = (monotonic_us() / 1000) - resp->elapsed_ms; 73 resp->elapsed_ms = (monotonic_us() / 1000) - resp->elapsed_ms;
76 resp->waitstatus = status;
77 return 1;
78} 74}
79 75
80/* Print ARGV, with each entry in ARGV separated by FILLER. */ 76static void printargv(char *const *argv)
81static void printargv(char *const *argv, const char *filler)
82{ 77{
83 fputs(*argv, stdout); 78 const char *fmt = " %s" + 1;
84 while (*++argv) { 79 do {
85 fputs(filler, stdout); 80 printf(fmt, *argv);
86 fputs(*argv, stdout); 81 fmt = " %s";
87 } 82 } while (*++argv);
88} 83}
89 84
90/* Return the number of kilobytes corresponding to a number of pages PAGES. 85/* Return the number of kilobytes corresponding to a number of pages PAGES.
@@ -94,24 +89,18 @@ static void printargv(char *const *argv, const char *filler)
94 This is funky since the pagesize could be less than 1K. 89 This is funky since the pagesize could be less than 1K.
95 Note: Some machines express getrusage statistics in terms of K, 90 Note: Some machines express getrusage statistics in terms of K,
96 others in terms of pages. */ 91 others in terms of pages. */
97 92static unsigned long ptok(unsigned pagesize, unsigned long pages)
98static unsigned long ptok(unsigned long pages)
99{ 93{
100 static unsigned long ps;
101 unsigned long tmp; 94 unsigned long tmp;
102 95
103 /* Initialization. */
104 if (ps == 0)
105 ps = getpagesize();
106
107 /* Conversion. */ 96 /* Conversion. */
108 if (pages > (LONG_MAX / ps)) { /* Could overflow. */ 97 if (pages > (LONG_MAX / pagesize)) { /* Could overflow. */
109 tmp = pages / 1024; /* Smaller first, */ 98 tmp = pages / 1024; /* Smaller first, */
110 return tmp * ps; /* then larger. */ 99 return tmp * pagesize; /* then larger. */
111 } 100 }
112 /* Could underflow. */ 101 /* Could underflow. */
113 tmp = pages * ps; /* Larger first, */ 102 tmp = pages * pagesize; /* Larger first, */
114 return tmp / 1024; /* then smaller. */ 103 return tmp / 1024; /* then smaller. */
115} 104}
116 105
117/* summarize: Report on the system use of a command. 106/* summarize: Report on the system use of a command.
@@ -162,15 +151,18 @@ static unsigned long ptok(unsigned long pages)
162#define TICKS_PER_SEC 100 151#define TICKS_PER_SEC 100
163#endif 152#endif
164 153
165static void summarize(const char *fmt, char **command, resource_t * resp) 154static void summarize(const char *fmt, char **command, resource_t *resp)
166{ 155{
167 unsigned vv_ms; /* Elapsed virtual (CPU) milliseconds */ 156 unsigned vv_ms; /* Elapsed virtual (CPU) milliseconds */
168 unsigned cpu_ticks; /* Same, in "CPU ticks" */ 157 unsigned cpu_ticks; /* Same, in "CPU ticks" */
158 unsigned pagesize = getpagesize();
169 159
160 /* Impossible: we do not use WUNTRACED flag in wait()...
170 if (WIFSTOPPED(resp->waitstatus)) 161 if (WIFSTOPPED(resp->waitstatus))
171 printf("Command stopped by signal %u\n", 162 printf("Command stopped by signal %u\n",
172 WSTOPSIG(resp->waitstatus)); 163 WSTOPSIG(resp->waitstatus));
173 else if (WIFSIGNALED(resp->waitstatus)) 164 else */
165 if (WIFSIGNALED(resp->waitstatus))
174 printf("Command terminated by signal %u\n", 166 printf("Command terminated by signal %u\n",
175 WTERMSIG(resp->waitstatus)); 167 WTERMSIG(resp->waitstatus));
176 else if (WIFEXITED(resp->waitstatus) && WEXITSTATUS(resp->waitstatus)) 168 else if (WIFEXITED(resp->waitstatus) && WEXITSTATUS(resp->waitstatus))
@@ -181,7 +173,7 @@ static void summarize(const char *fmt, char **command, resource_t * resp)
181 + (resp->ru.ru_utime.tv_usec + resp->ru.ru_stime.tv_usec) / 1000; 173 + (resp->ru.ru_utime.tv_usec + resp->ru.ru_stime.tv_usec) / 1000;
182 174
183#if (1000 / TICKS_PER_SEC) * TICKS_PER_SEC == 1000 175#if (1000 / TICKS_PER_SEC) * TICKS_PER_SEC == 1000
184 /* 1000 is exactly divisible by TICKS_PER_SEC */ 176 /* 1000 is exactly divisible by TICKS_PER_SEC (typical) */
185 cpu_ticks = vv_ms / (1000 / TICKS_PER_SEC); 177 cpu_ticks = vv_ms / (1000 / TICKS_PER_SEC);
186#else 178#else
187 cpu_ticks = vv_ms * (unsigned long long)TICKS_PER_SEC / 1000; 179 cpu_ticks = vv_ms * (unsigned long long)TICKS_PER_SEC / 1000;
@@ -221,12 +213,12 @@ static void summarize(const char *fmt, char **command, resource_t * resp)
221 break; 213 break;
222#endif 214#endif
223 case 'C': /* The command that got timed. */ 215 case 'C': /* The command that got timed. */
224 printargv(command, " "); 216 printargv(command);
225 break; 217 break;
226 case 'D': /* Average unshared data size. */ 218 case 'D': /* Average unshared data size. */
227 printf("%lu", 219 printf("%lu",
228 ptok((UL) resp->ru.ru_idrss) / cpu_ticks + 220 (ptok(pagesize, (UL) resp->ru.ru_idrss) +
229 ptok((UL) resp->ru.ru_isrss) / cpu_ticks); 221 ptok(pagesize, (UL) resp->ru.ru_isrss)) / cpu_ticks);
230 break; 222 break;
231 case 'E': { /* Elapsed real (wall clock) time. */ 223 case 'E': { /* Elapsed real (wall clock) time. */
232 unsigned seconds = resp->elapsed_ms / 1000; 224 unsigned seconds = resp->elapsed_ms / 1000;
@@ -250,12 +242,12 @@ static void summarize(const char *fmt, char **command, resource_t * resp)
250 break; 242 break;
251 case 'K': /* Average mem usage == data+stack+text. */ 243 case 'K': /* Average mem usage == data+stack+text. */
252 printf("%lu", 244 printf("%lu",
253 ptok((UL) resp->ru.ru_idrss) / cpu_ticks + 245 (ptok(pagesize, (UL) resp->ru.ru_idrss) +
254 ptok((UL) resp->ru.ru_isrss) / cpu_ticks + 246 ptok(pagesize, (UL) resp->ru.ru_isrss) +
255 ptok((UL) resp->ru.ru_ixrss) / cpu_ticks); 247 ptok(pagesize, (UL) resp->ru.ru_ixrss)) / cpu_ticks);
256 break; 248 break;
257 case 'M': /* Maximum resident set size. */ 249 case 'M': /* Maximum resident set size. */
258 printf("%lu", ptok((UL) resp->ru.ru_maxrss)); 250 printf("%lu", ptok(pagesize, (UL) resp->ru.ru_maxrss));
259 break; 251 break;
260 case 'O': /* Outputs. */ 252 case 'O': /* Outputs. */
261 printf("%lu", resp->ru.ru_oublock); 253 printf("%lu", resp->ru.ru_oublock);
@@ -308,7 +300,7 @@ static void summarize(const char *fmt, char **command, resource_t * resp)
308 printf("%lu", resp->ru.ru_nswap); 300 printf("%lu", resp->ru.ru_nswap);
309 break; 301 break;
310 case 'X': /* Average shared text size. */ 302 case 'X': /* Average shared text size. */
311 printf("%lu", ptok((UL) resp->ru.ru_ixrss) / cpu_ticks); 303 printf("%lu", ptok(pagesize, (UL) resp->ru.ru_ixrss) / cpu_ticks);
312 break; 304 break;
313 case 'Z': /* Page size. */ 305 case 'Z': /* Page size. */
314 printf("%u", getpagesize()); 306 printf("%u", getpagesize());
@@ -325,7 +317,7 @@ static void summarize(const char *fmt, char **command, resource_t * resp)
325 printf("%lu", resp->ru.ru_nsignals); 317 printf("%lu", resp->ru.ru_nsignals);
326 break; 318 break;
327 case 'p': /* Average stack segment. */ 319 case 'p': /* Average stack segment. */
328 printf("%lu", ptok((UL) resp->ru.ru_isrss) / cpu_ticks); 320 printf("%lu", ptok(pagesize, (UL) resp->ru.ru_isrss) / cpu_ticks);
329 break; 321 break;
330 case 'r': /* Incoming socket messages received. */ 322 case 'r': /* Incoming socket messages received. */
331 printf("%lu", resp->ru.ru_msgrcv); 323 printf("%lu", resp->ru.ru_msgrcv);
@@ -334,7 +326,7 @@ static void summarize(const char *fmt, char **command, resource_t * resp)
334 printf("%lu", resp->ru.ru_msgsnd); 326 printf("%lu", resp->ru.ru_msgsnd);
335 break; 327 break;
336 case 't': /* Average resident set size. */ 328 case 't': /* Average resident set size. */
337 printf("%lu", ptok((UL) resp->ru.ru_idrss) / cpu_ticks); 329 printf("%lu", ptok(pagesize, (UL) resp->ru.ru_idrss) / cpu_ticks);
338 break; 330 break;
339 case 'w': /* Voluntary context switches. */ 331 case 'w': /* Voluntary context switches. */
340 printf("%lu", resp->ru.ru_nvcsw); 332 printf("%lu", resp->ru.ru_nvcsw);
@@ -396,8 +388,7 @@ static void run_command(char *const *cmd, resource_t *resp)
396 interrupt_signal = signal(SIGINT, SIG_IGN); 388 interrupt_signal = signal(SIGINT, SIG_IGN);
397 quit_signal = signal(SIGQUIT, SIG_IGN); 389 quit_signal = signal(SIGQUIT, SIG_IGN);
398 390
399 if (resuse_end(pid, resp) == 0) 391 resuse_end(pid, resp);
400 bb_error_msg("error waiting for child process");
401 392
402 /* Re-enable signals. */ 393 /* Re-enable signals. */
403 signal(SIGINT, interrupt_signal); 394 signal(SIGINT, interrupt_signal);
@@ -405,41 +396,26 @@ static void run_command(char *const *cmd, resource_t *resp)
405} 396}
406 397
407int time_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 398int time_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
408int time_main(int argc, char **argv) 399int time_main(int argc ATTRIBUTE_UNUSED, char **argv)
409{ 400{
410 resource_t res; 401 resource_t res;
411 const char *output_format = default_format; 402 const char *output_format = default_format;
412 char c; 403 int opt;
413 404
414 goto next; 405 /* "+": stop on first non-option */
415 /* Parse any options -- don't use getopt() here so we don't 406 opt = getopt32(argv, "+vp");
416 * consume the args of our client application... */ 407 argv += optind;
417 while (argc > 0 && argv[0][0] == '-') { 408 if (opt & 1)
418 while ((c = *++*argv)) { 409 output_format = long_format;
419 switch (c) { 410 if (opt & 2)
420 case 'v': 411 output_format = posix_format;
421 output_format = long_format;
422 break;
423 case 'p':
424 output_format = posix_format;
425 break;
426 default:
427 bb_show_usage();
428 }
429 }
430 next:
431 argv++;
432 argc--;
433 if (!argc)
434 bb_show_usage();
435 }
436 412
437 run_command(argv, &res); 413 run_command(argv, &res);
438 414
439 /* Cheat. printf's are shorter :) */ 415 /* Cheat. printf's are shorter :) */
440 /* (but see bb_putchar() body for additional wrinkle!) */ 416 /* (but see bb_putchar() body for additional wrinkle!) */
417 xdup2(2, 1); /* just in case libc does something silly :( */
441 stdout = stderr; 418 stdout = stderr;
442 dup2(2, 1); /* just in case libc does something silly :( */
443 summarize(output_format, argv, &res); 419 summarize(output_format, argv, &res);
444 420
445 if (WIFSTOPPED(res.waitstatus)) 421 if (WIFSTOPPED(res.waitstatus))
diff --git a/miscutils/ttysize.c b/miscutils/ttysize.c
index f51b328ea..05455543d 100644
--- a/miscutils/ttysize.c
+++ b/miscutils/ttysize.c
@@ -14,7 +14,7 @@
14int ttysize_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 14int ttysize_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
15int ttysize_main(int argc, char **argv) 15int ttysize_main(int argc, char **argv)
16{ 16{
17 unsigned w,h; 17 unsigned w, h;
18 struct winsize wsz; 18 struct winsize wsz;
19 19
20 w = 80; 20 w = 80;
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c
index 28bd35813..7fb16b861 100644
--- a/miscutils/watchdog.c
+++ b/miscutils/watchdog.c
@@ -13,8 +13,7 @@
13#define OPT_FOREGROUND 0x01 13#define OPT_FOREGROUND 0x01
14#define OPT_TIMER 0x02 14#define OPT_TIMER 0x02
15 15
16static void watchdog_shutdown(int ATTRIBUTE_UNUSED sig) ATTRIBUTE_NORETURN; 16static void watchdog_shutdown(int sig ATTRIBUTE_UNUSED)
17static void watchdog_shutdown(int ATTRIBUTE_UNUSED sig)
18{ 17{
19 static const char V = 'V'; 18 static const char V = 'V';
20 19
@@ -47,14 +46,19 @@ int watchdog_main(int argc, char **argv)
47 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); 46 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
48 } 47 }
49 48
50 bb_signals(0 49 bb_signals(BB_SIGS_FATAL, watchdog_shutdown);
51 + (1 << SIGHUP)
52 + (1 << SIGINT)
53 , watchdog_shutdown);
54 50
55 /* Use known fd # - avoid needing global 'int fd' */ 51 /* Use known fd # - avoid needing global 'int fd' */
56 xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3); 52 xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3);
57 53
54// TODO?
55// if (!(opts & OPT_TIMER)) {
56// if (ioctl(fd, WDIOC_GETTIMEOUT, &timer_duration) == 0)
57// timer_duration *= 500;
58// else
59// timer_duration = 30000;
60// }
61
58 while (1) { 62 while (1) {
59 /* 63 /*
60 * Make sure we clear the counter before sleeping, as the counter value 64 * Make sure we clear the counter before sleeping, as the counter value
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index 058e8bed7..7ef544936 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -64,7 +64,7 @@
64 * 06.11.96 - Added v2 code submitted by Joerg Dorchain, but written by 64 * 06.11.96 - Added v2 code submitted by Joerg Dorchain, but written by
65 * Andreas Schwab. 65 * Andreas Schwab.
66 * 66 *
67 * 1999-02-22 Arkadiusz Mikiewicz <misiek@misiek.eu.org> 67 * 1999-02-22 Arkadiusz Mickiewicz <misiek@misiek.eu.org>
68 * - added Native Language Support 68 * - added Native Language Support
69 * 69 *
70 * 70 *
diff --git a/util-linux/getopt.c b/util-linux/getopt.c
index ee6c14393..6ec5cb0cd 100644
--- a/util-linux/getopt.c
+++ b/util-linux/getopt.c
@@ -22,7 +22,7 @@
22 * Version 1.0.6: Tue Jun 27 2000 22 * Version 1.0.6: Tue Jun 27 2000
23 * No important changes 23 * No important changes
24 * Version 1.1.0: Tue Jun 30 2000 24 * Version 1.1.0: Tue Jun 30 2000
25 * Added NLS support (partly written by Arkadiusz Mi<B6>kiewicz 25 * Added NLS support (partly written by Arkadiusz Mickiewicz
26 * <misiek@misiek.eu.org>) 26 * <misiek@misiek.eu.org>)
27 * Ported to Busybox - Alfred M. Szmidt <ams@trillian.itslinux.org> 27 * Ported to Busybox - Alfred M. Szmidt <ams@trillian.itslinux.org>
28 * Removed --version/-V and --help/-h in 28 * Removed --version/-V and --help/-h in
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 6e63a01fc..a0e6cda73 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -502,7 +502,7 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
502 * Wed Oct 1 23:55:28 1997: Dick Streefland <dick_streefland@tasking.com> 502 * Wed Oct 1 23:55:28 1997: Dick Streefland <dick_streefland@tasking.com>
503 * Implemented the "bg", "fg" and "retry" mount options for NFS. 503 * Implemented the "bg", "fg" and "retry" mount options for NFS.
504 * 504 *
505 * 1999-02-22 Arkadiusz Mikiewicz <misiek@misiek.eu.org> 505 * 1999-02-22 Arkadiusz Mickiewicz <misiek@misiek.eu.org>
506 * - added Native Language Support 506 * - added Native Language Support
507 * 507 *
508 * Modified by Olaf Kirch and Trond Myklebust for new NFS code, 508 * Modified by Olaf Kirch and Trond Myklebust for new NFS code,