diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-17 09:29:43 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-17 09:29:43 +0000 |
commit | b44c790e41e281965955a83408f35ea53ecdb3d2 (patch) | |
tree | 98514dba64f7b74b9d60882bfeca1e2c4976b033 | |
parent | d25c33f186c7cf3618c34ce79af94fe156f9ab02 (diff) | |
download | busybox-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.htm | 4 | ||||
-rw-r--r-- | include/libbb.h | 4 | ||||
-rw-r--r-- | include/usage.h | 2 | ||||
-rw-r--r-- | loginutils/getty.c | 5 | ||||
-rw-r--r-- | miscutils/chrt.c | 92 | ||||
-rw-r--r-- | miscutils/crond.c | 4 | ||||
-rw-r--r-- | miscutils/crontab.c | 11 | ||||
-rw-r--r-- | miscutils/dc.c | 94 | ||||
-rw-r--r-- | miscutils/eject.c | 95 | ||||
-rw-r--r-- | miscutils/last.c | 2 | ||||
-rw-r--r-- | miscutils/setsid.c | 10 | ||||
-rw-r--r-- | miscutils/taskset.c | 88 | ||||
-rw-r--r-- | miscutils/time.c | 118 | ||||
-rw-r--r-- | miscutils/ttysize.c | 2 | ||||
-rw-r--r-- | miscutils/watchdog.c | 16 | ||||
-rw-r--r-- | util-linux/fsck_minix.c | 2 | ||||
-rw-r--r-- | util-linux/getopt.c | 2 | ||||
-rw-r--r-- | util-linux/mount.c | 2 |
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) | |||
145 | of processes. With a shell that does not know about job control, | 145 | of processes. With a shell that does not know about job control, |
146 | like <code>ash</code>, each of its children will be in the same session | 146 | like <code>ash</code>, each of its children will be in the same session |
147 | and have the same process group as the shell. With a shell that knows | 147 | and have the same process group as the shell. With a shell that knows |
148 | about job control, like <code>bash</code>, the processes of one pipeline. like | 148 | about 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 > out | 150 | <pre>% cat paper | ideal | pic | tbl | eqn | ditroff > out |
151 | </pre> | 151 | </pre> |
@@ -227,7 +227,7 @@ controlling tty. If there is none, this returns a random value | |||
227 | larger than 1 that is not a process group ID. | 227 | larger 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 |
229 | using <code>tcsetpgrp(fd,pgrp)</code>, where <code>fd</code> refers to its | 229 | using <code>tcsetpgrp(fd,pgrp)</code>, where <code>fd</code> refers to its |
230 | controlling tty, and <code>pgrp</code> is a process group in the | 230 | controlling tty, and <code>pgrp</code> is a process group in |
231 | its session, and this session still is associated to the controlling | 231 | its session, and this session still is associated to the controlling |
232 | tty of the calling process. | 232 | tty 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 Mi¶kiewicz <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 |
15 | static const struct { | 15 | static 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 | ||
44 | int chrt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 44 | int chrt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
45 | int chrt_main(int argc, char **argv) | 45 | int 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; |
94 | print_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 | ||
160 | int crond_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 160 | int crond_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
161 | int crond_main(int ac ATTRIBUTE_UNUSED, char **av) | 161 | int 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 | ||
25 | static void change_user(const struct passwd *pas) | 22 | static 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 | ||
11 | enum { STACK_SIZE = COMMON_BUFSIZE / sizeof(double) }; | ||
12 | 11 | ||
13 | #define stack ((double*)&bb_common_bufsiz1) | 12 | struct globals { |
14 | static unsigned int pointer; | 13 | unsigned pointer; |
15 | static unsigned char base; | 14 | unsigned base; |
15 | double stack[1]; | ||
16 | }; | ||
17 | enum { 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 | ||
17 | static void push(double a) | 24 | static void push(double a) |
18 | { | 25 | { |
@@ -61,34 +68,34 @@ static void divide(void) | |||
61 | 68 | ||
62 | static void mod(void) | 69 | static 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 | ||
69 | static void and(void) | 76 | static void and(void) |
70 | { | 77 | { |
71 | push((unsigned int) pop() & (unsigned int) pop()); | 78 | push((unsigned) pop() & (unsigned) pop()); |
72 | } | 79 | } |
73 | 80 | ||
74 | static void or(void) | 81 | static void or(void) |
75 | { | 82 | { |
76 | push((unsigned int) pop() | (unsigned int) pop()); | 83 | push((unsigned) pop() | (unsigned) pop()); |
77 | } | 84 | } |
78 | 85 | ||
79 | static void eor(void) | 86 | static void eor(void) |
80 | { | 87 | { |
81 | push((unsigned int) pop() ^ (unsigned int) pop()); | 88 | push((unsigned) pop() ^ (unsigned) pop()); |
82 | } | 89 | } |
83 | 90 | ||
84 | static void not(void) | 91 | static void not(void) |
85 | { | 92 | { |
86 | push(~(unsigned int) pop()); | 93 | push(~(unsigned) pop()); |
87 | } | 94 | } |
88 | 95 | ||
89 | static void set_output_base(void) | 96 | static 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) | |||
98 | static void print_base(double print) | 105 | static 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 | ||
106 | static void print_stack_no_pop(void) | 113 | static 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 | ||
148 | static void stack_machine(const char *argument) | 155 | static 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 | */ |
177 | static char *get_token(char **buffer) | 184 | static 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 */ | ||
192 | static 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 | ||
200 | int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 194 | int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
201 | int dc_main(int argc, char **argv) | 195 | int 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> |
35 | static void eject_scsi(const int fd, const char * const dev) | 32 | |
33 | static 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 | ||
69 | static 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 | |||
72 | static 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 | ||
81 | int eject_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 85 | int eject_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
82 | int eject_main(int argc ATTRIBUTE_UNUSED, char **argv) | 86 | int 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 Mi¶kiewicz <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 | ||
19 | int setsid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 19 | int setsid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
20 | int setsid_main(int argc, char **argv) | 20 | int 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 | ||
44 | int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 43 | int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
45 | int taskset_main(int argc, char **argv) | 44 | int 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 .*/ |
29 | static const char posix_format[] ALIGN1 = "real %e\nuser %U\nsys %S"; | 29 | static 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.*/ |
34 | static const char long_format[] ALIGN1 = | 33 | static 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. */ |
64 | static int resuse_end(pid_t pid, resource_t *resp) | 61 | static 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. */ | 76 | static void printargv(char *const *argv) |
81 | static 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 | 92 | static unsigned long ptok(unsigned pagesize, unsigned long pages) | |
98 | static 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 | ||
165 | static void summarize(const char *fmt, char **command, resource_t * resp) | 154 | static 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 | ||
407 | int time_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 398 | int time_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
408 | int time_main(int argc, char **argv) | 399 | int 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 @@ | |||
14 | int ttysize_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 14 | int ttysize_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
15 | int ttysize_main(int argc, char **argv) | 15 | int 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 | ||
16 | static void watchdog_shutdown(int ATTRIBUTE_UNUSED sig) ATTRIBUTE_NORETURN; | 16 | static void watchdog_shutdown(int sig ATTRIBUTE_UNUSED) |
17 | static 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 Mi¶kiewicz <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 Mi¶kiewicz <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, |