aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-10-08 23:36:17 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-10-08 23:36:17 +0000
commitca3c981c07ade7f8fd50ba4bb452a2fadaddc326 (patch)
tree8763d9f89197adda0ef45ac57418743766345fe4
parent7039a66b58706457c7423de60556e04545432943 (diff)
downloadbusybox-w32-ca3c981c07ade7f8fd50ba4bb452a2fadaddc326.tar.gz
busybox-w32-ca3c981c07ade7f8fd50ba4bb452a2fadaddc326.tar.bz2
busybox-w32-ca3c981c07ade7f8fd50ba4bb452a2fadaddc326.zip
start_stop_daemon: add -N <nice> compat
[re]nice: add support for -nNNN w/o spaces, -NNN (nice only), simplified code
-rw-r--r--coreutils/nice.c44
-rw-r--r--debianutils/start_stop_daemon.c73
-rw-r--r--include/libbb.h1
-rw-r--r--include/usage.h1
-rw-r--r--libbb/xatol.c5
-rw-r--r--procps/renice.c55
6 files changed, 87 insertions, 92 deletions
diff --git a/coreutils/nice.c b/coreutils/nice.c
index a347001e3..dbd90648d 100644
--- a/coreutils/nice.c
+++ b/coreutils/nice.c
@@ -7,39 +7,14 @@
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8 */ 8 */
9 9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <limits.h>
14#include <errno.h>
15#include <unistd.h>
16#include <sys/resource.h> 10#include <sys/resource.h>
17#include "busybox.h" 11#include "busybox.h"
18 12
19static inline int int_add_no_wrap(int a, int b)
20{
21 int s = a + b;
22
23 if (b < 0) {
24 if (s > a) s = INT_MIN;
25 } else {
26 if (s < a) s = INT_MAX;
27 }
28
29 return s;
30}
31
32int nice_main(int argc, char **argv) 13int nice_main(int argc, char **argv)
33{ 14{
34 static const char Xetpriority_msg[] = "cannot %cet priority";
35
36 int old_priority, adjustment; 15 int old_priority, adjustment;
37 16
38 errno = 0; /* Needed for getpriority error detection. */
39 old_priority = getpriority(PRIO_PROCESS, 0); 17 old_priority = getpriority(PRIO_PROCESS, 0);
40 if (errno) {
41 bb_perror_msg_and_die(Xetpriority_msg, 'g');
42 }
43 18
44 if (!*++argv) { /* No args, so (GNU) output current nice value. */ 19 if (!*++argv) { /* No args, so (GNU) output current nice value. */
45 bb_printf("%d\n", old_priority); 20 bb_printf("%d\n", old_priority);
@@ -48,19 +23,26 @@ int nice_main(int argc, char **argv)
48 23
49 adjustment = 10; /* Set default adjustment. */ 24 adjustment = 10; /* Set default adjustment. */
50 25
51 if ((argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) { /* "-n" */ 26 if (argv[0][0] == '-') {
27 if (argv[0][1] == 'n') { /* -n */
28 if (argv[0][2]) { /* -nNNNN (w/o space) */
29 argv[0] += 2; argv--; argc++;
30 }
31 } else { /* -NNN (NNN may be negative) == -n NNN */
32 argv[0] += 1; argv--; argc++;
33 }
52 if (argc < 4) { /* Missing priority and/or utility! */ 34 if (argc < 4) { /* Missing priority and/or utility! */
53 bb_show_usage(); 35 bb_show_usage();
54 } 36 }
55 adjustment = xatoi(argv[1]); 37 adjustment = xatoi_range(argv[1], INT_MIN/2, INT_MAX/2);
56 argv += 2; 38 argv += 2;
57 } 39 }
58 40
59 { /* Set our priority. Handle integer wrapping for old + adjust. */ 41 { /* Set our priority. */
60 int new_priority = int_add_no_wrap(old_priority, adjustment); 42 int prio = old_priority + adjustment;
61 43
62 if (setpriority(PRIO_PROCESS, 0, new_priority) < 0) { 44 if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
63 bb_perror_msg_and_die(Xetpriority_msg, 's'); 45 bb_perror_msg_and_die("setpriority(%d)", prio);
64 } 46 }
65 } 47 }
66 48
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
index 6ced9caad..a9f82c5cc 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -10,6 +10,7 @@
10 10
11#include "busybox.h" 11#include "busybox.h"
12#include <getopt.h> 12#include <getopt.h>
13#include <sys/resource.h>
13 14
14static int signal_nr = 15; 15static int signal_nr = 15;
15static int user_id = -1; 16static int user_id = -1;
@@ -191,38 +192,39 @@ static int do_stop(void)
191 192
192#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS 193#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
193static const struct option ssd_long_options[] = { 194static const struct option ssd_long_options[] = {
194 { "stop", 0, NULL, 'K' }, 195 { "stop", 0, NULL, 'K' },
195 { "start", 0, NULL, 'S' }, 196 { "start", 0, NULL, 'S' },
196 { "background", 0, NULL, 'b' }, 197 { "background", 0, NULL, 'b' },
197 { "quiet", 0, NULL, 'q' }, 198 { "quiet", 0, NULL, 'q' },
198 { "make-pidfile", 0, NULL, 'm' }, 199 { "make-pidfile", 0, NULL, 'm' },
199#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY 200#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
200 { "oknodo", 0, NULL, 'o' }, 201 { "oknodo", 0, NULL, 'o' },
201 { "verbose", 0, NULL, 'v' }, 202 { "verbose", 0, NULL, 'v' },
203 { "nicelevel", 1, NULL, 'N' },
202#endif 204#endif
203 { "startas", 1, NULL, 'a' }, 205 { "startas", 1, NULL, 'a' },
204 { "name", 1, NULL, 'n' }, 206 { "name", 1, NULL, 'n' },
205 { "signal", 1, NULL, 's' }, 207 { "signal", 1, NULL, 's' },
206 { "user", 1, NULL, 'u' }, 208 { "user", 1, NULL, 'u' },
207 { "chuid", 1, NULL, 'c' }, 209 { "chuid", 1, NULL, 'c' },
208 { "exec", 1, NULL, 'x' }, 210 { "exec", 1, NULL, 'x' },
209 { "pidfile", 1, NULL, 'p' }, 211 { "pidfile", 1, NULL, 'p' },
210#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY 212#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
211 { "retry", 1, NULL, 'R' }, 213 { "retry", 1, NULL, 'R' },
212#endif 214#endif
213 { 0, 0, 0, 0 } 215 { 0, 0, 0, 0 }
214}; 216};
215#endif 217#endif
216 218
217#define SSD_CTX_STOP 1 219#define SSD_CTX_STOP 0x1
218#define SSD_CTX_START 2 220#define SSD_CTX_START 0x2
219#define SSD_OPT_BACKGROUND 4 221#define SSD_OPT_BACKGROUND 0x4
220#define SSD_OPT_QUIET 8 222#define SSD_OPT_QUIET 0x8
221#define SSD_OPT_MAKEPID 16 223#define SSD_OPT_MAKEPID 0x10
222#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY 224#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
223#define SSD_OPT_OKNODO 32 225#define SSD_OPT_OKNODO 0x20
224#define SSD_OPT_VERBOSE 64 226#define SSD_OPT_VERBOSE 0x40
225 227#define SSD_OPT_NICELEVEL 0x80
226#endif 228#endif
227 229
228int start_stop_daemon_main(int argc, char **argv) 230int start_stop_daemon_main(int argc, char **argv)
@@ -233,6 +235,7 @@ int start_stop_daemon_main(int argc, char **argv)
233#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY 235#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
234// char *retry_arg = NULL; 236// char *retry_arg = NULL;
235// int retries = -1; 237// int retries = -1;
238 char *opt_N;
236#endif 239#endif
237#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS 240#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
238 applet_long_options = ssd_long_options; 241 applet_long_options = ssd_long_options;
@@ -241,9 +244,10 @@ int start_stop_daemon_main(int argc, char **argv)
241 /* Check required one context option was given */ 244 /* Check required one context option was given */
242 opt_complementary = "K:S:?:K--S:S--K:m?p:K?xpun:S?xa"; 245 opt_complementary = "K:S:?:K--S:S--K:m?p:K?xpun:S?xa";
243 opt = getopt32(argc, argv, "KSbqm" 246 opt = getopt32(argc, argv, "KSbqm"
244// USE_FEATURE_START_STOP_DAEMON_FANCY("ovR:") 247// USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:")
245 USE_FEATURE_START_STOP_DAEMON_FANCY("ov") 248 USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:")
246 "a:n:s:u:c:x:p:" 249 "a:n:s:u:c:x:p:"
250 USE_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N)
247// USE_FEATURE_START_STOP_DAEMON_FANCY(,&retry_arg) 251// USE_FEATURE_START_STOP_DAEMON_FANCY(,&retry_arg)
248 ,&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile); 252 ,&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile);
249 253
@@ -279,7 +283,7 @@ int start_stop_daemon_main(int argc, char **argv)
279 283
280 if (found) { 284 if (found) {
281 if (!quiet) 285 if (!quiet)
282 printf("%s already running.\n%d\n", execname ,found->pid); 286 printf("%s already running\n%d\n", execname, found->pid);
283 USE_FEATURE_START_STOP_DAEMON_FANCY(return !(opt & SSD_OPT_OKNODO);) 287 USE_FEATURE_START_STOP_DAEMON_FANCY(return !(opt & SSD_OPT_OKNODO);)
284 SKIP_FEATURE_START_STOP_DAEMON_FANCY(return EXIT_FAILURE;) 288 SKIP_FEATURE_START_STOP_DAEMON_FANCY(return EXIT_FAILURE;)
285 } 289 }
@@ -296,11 +300,20 @@ int start_stop_daemon_main(int argc, char **argv)
296 fprintf(pidf, "%d\n", pidt); 300 fprintf(pidf, "%d\n", pidt);
297 fclose(pidf); 301 fclose(pidf);
298 } 302 }
299 if(chuid) { 303 if (chuid) {
300 if(sscanf(chuid, "%d", &user_id) != 1) 304 if (sscanf(chuid, "%d", &user_id) != 1)
301 user_id = bb_xgetpwnam(chuid); 305 user_id = bb_xgetpwnam(chuid);
302 setuid(user_id); 306 xsetuid(user_id);
303 } 307 }
308#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
309 if (opt & SSD_OPT_NICELEVEL) {
310 /* Set process priority */
311 int prio = getpriority(PRIO_PROCESS, 0) + xatoi_range(opt_N, INT_MIN/2, INT_MAX/2);
312 if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
313 bb_perror_msg_and_die("setpriority(%d)", prio);
314 }
315 }
316#endif
304 execv(startas, argv); 317 execv(startas, argv);
305 bb_perror_msg_and_die ("unable to start %s", startas); 318 bb_perror_msg_and_die ("unable to start %s", startas);
306} 319}
diff --git a/include/libbb.h b/include/libbb.h
index bc86e5faf..7b9b83908 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -346,6 +346,7 @@ long xatol_sfx(const char *numstr, const struct suffix_mult *suffixes);
346long xatol(const char *numstr); 346long xatol(const char *numstr);
347/* Specialized: */ 347/* Specialized: */
348unsigned xatou(const char *numstr); 348unsigned xatou(const char *numstr);
349int xatoi_range(const char *numstr, int lower, int upper);
349int xatoi(const char *numstr); 350int xatoi(const char *numstr);
350/* Using xatoi() instead of naive atoi() is not always convenient - 351/* Using xatoi() instead of naive atoi() is not always convenient -
351 * in many places people want *non-negative* values, but store them 352 * in many places people want *non-negative* values, but store them
diff --git a/include/usage.h b/include/usage.h
index c9e501903..ef348a2a9 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -2691,6 +2691,7 @@ USE_FEATURE_MDEV_CONFIG( \
2691USE_FEATURE_START_STOP_DAEMON_FANCY( \ 2691USE_FEATURE_START_STOP_DAEMON_FANCY( \
2692 "\n\t-o|--oknodo\t\t\texit status 0 if nothing done" \ 2692 "\n\t-o|--oknodo\t\t\texit status 0 if nothing done" \
2693 "\n\t-v|--verbose\t\t\tbe verbose" \ 2693 "\n\t-v|--verbose\t\t\tbe verbose" \
2694 "\n\t-N|--nicelevel <N>\t\tadd N to process's nice level" \
2694) \ 2695) \
2695 "\n\t-s|--signal <signal>\t\tsignal to send (default TERM)" \ 2696 "\n\t-s|--signal <signal>\t\tsignal to send (default TERM)" \
2696 "\n\t-U|--chuid <username>|<uid>\tstart process with this name" 2697 "\n\t-U|--chuid <username>|<uid>\tstart process with this name"
diff --git a/libbb/xatol.c b/libbb/xatol.c
index 82250a7bb..3316c3d06 100644
--- a/libbb/xatol.c
+++ b/libbb/xatol.c
@@ -189,6 +189,11 @@ unsigned xatou(const char *numstr)
189 return xatoul_range(numstr, 0, UINT_MAX); 189 return xatoul_range(numstr, 0, UINT_MAX);
190} 190}
191 191
192int xatoi_range(const char *numstr, int lower, int upper)
193{
194 return xatol_range(numstr, lower, upper);
195}
196
192int xatoi(const char *numstr) 197int xatoi(const char *numstr)
193{ 198{
194 return xatol_range(numstr, INT_MIN, INT_MAX); 199 return xatol_range(numstr, INT_MIN, INT_MAX);
diff --git a/procps/renice.c b/procps/renice.c
index a91328f53..bcaa94cf1 100644
--- a/procps/renice.c
+++ b/procps/renice.c
@@ -38,68 +38,61 @@
38#error Assumption violated : PRIO_USER value 38#error Assumption violated : PRIO_USER value
39#endif 39#endif
40 40
41static inline int int_add_no_wrap(int a, int b)
42{
43 int s = a + b;
44
45 if (b < 0) {
46 if (s > a) s = INT_MIN;
47 } else {
48 if (s < a) s = INT_MAX;
49 }
50
51 return s;
52}
53
54int renice_main(int argc, char **argv) 41int renice_main(int argc, char **argv)
55{ 42{
56 static const char Xetpriority_msg[] = "%d: %cetpriority"; 43 static const char Xetpriority_msg[] = "%cetpriority";
57 44
58 int retval = EXIT_SUCCESS; 45 int retval = EXIT_SUCCESS;
59 int which = PRIO_PROCESS; /* Default 'which' value. */ 46 int which = PRIO_PROCESS; /* Default 'which' value. */
60 int use_relative = 0; 47 int use_relative = 0;
61 int adjustment, new_priority; 48 int adjustment, new_priority;
62 unsigned who; 49 unsigned who;
50 char *arg;
63 51
64 ++argv; 52 arg = *++argv;
65 53
66 /* Check if we are using a relative adjustment. */ 54 /* Check if we are using a relative adjustment. */
67 if (argv[0] && (argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) { 55 if (arg && arg[0] == '-' && arg[1] == 'n') {
68 use_relative = 1; 56 use_relative = 1;
69 ++argv; 57 if (!arg[2])
58 arg = *++argv;
59 else
60 arg += 2;
70 } 61 }
71 62
72 if (!*argv) { /* No args? Then show usage. */ 63 if (!arg) { /* No args? Then show usage. */
73 bb_show_usage(); 64 bb_show_usage();
74 } 65 }
75 66
76 /* Get the priority adjustment (absolute or relative). */ 67 /* Get the priority adjustment (absolute or relative). */
77 adjustment = xatoi(*argv); 68 adjustment = xatoi_range(arg, INT_MIN/2, INT_MAX/2);
78 69
79 while (*++argv) { 70 while ((arg = *++argv) != NULL) {
80 /* Check for a mode switch. */ 71 /* Check for a mode switch. */
81 if ((argv[0][0] == '-') && argv[0][1] && !argv[0][2]) { 72 if (arg[0] == '-' && arg[1]) {
82 static const char opts[] 73 static const char opts[]
83 = { 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER }; 74 = { 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER };
84 const char *p = strchr(opts, argv[0][1]); 75 const char *p = strchr(opts, arg[1]);
85 if (p) { 76 if (p) {
86 which = p[4]; 77 which = p[4];
87 continue; 78 if (!arg[2])
79 continue;
80 arg += 2;
88 } 81 }
89 } 82 }
90 83
91 /* Process an ID arg. */ 84 /* Process an ID arg. */
92 if (which == PRIO_USER) { 85 if (which == PRIO_USER) {
93 struct passwd *p; 86 struct passwd *p;
94 p = getpwnam(*argv); 87 p = getpwnam(arg);
95 if (!p) { 88 if (!p) {
96 bb_error_msg("unknown user: %s", *argv); 89 bb_error_msg("unknown user: %s", arg);
97 goto HAD_ERROR; 90 goto HAD_ERROR;
98 } 91 }
99 who = p->pw_uid; 92 who = p->pw_uid;
100 } else { 93 } else {
101 if (safe_strtou(*argv, &who)) { 94 if (safe_strtou(arg, &who)) {
102 bb_error_msg("bad value: %s", *argv); 95 bb_error_msg("bad value: %s", arg);
103 goto HAD_ERROR; 96 goto HAD_ERROR;
104 } 97 }
105 } 98 }
@@ -111,11 +104,11 @@ int renice_main(int argc, char **argv)
111 errno = 0; /* Needed for getpriority error detection. */ 104 errno = 0; /* Needed for getpriority error detection. */
112 old_priority = getpriority(which, who); 105 old_priority = getpriority(which, who);
113 if (errno) { 106 if (errno) {
114 bb_perror_msg(Xetpriority_msg, who, 'g'); 107 bb_perror_msg(Xetpriority_msg, 'g');
115 goto HAD_ERROR; 108 goto HAD_ERROR;
116 } 109 }
117 110
118 new_priority = int_add_no_wrap(old_priority, adjustment); 111 new_priority = old_priority + adjustment;
119 } else { 112 } else {
120 new_priority = adjustment; 113 new_priority = adjustment;
121 } 114 }
@@ -124,8 +117,8 @@ int renice_main(int argc, char **argv)
124 continue; 117 continue;
125 } 118 }
126 119
127 bb_perror_msg(Xetpriority_msg, who, 's'); 120 bb_perror_msg(Xetpriority_msg, 's');
128 HAD_ERROR: 121 HAD_ERROR:
129 retval = EXIT_FAILURE; 122 retval = EXIT_FAILURE;
130 } 123 }
131 124