* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <errno.h>
-#include <unistd.h>
#include <sys/resource.h>
#include "busybox.h"
-static inline int int_add_no_wrap(int a, int b)
-{
- int s = a + b;
-
- if (b < 0) {
- if (s > a) s = INT_MIN;
- } else {
- if (s < a) s = INT_MAX;
- }
-
- return s;
-}
-
int nice_main(int argc, char **argv)
{
- static const char Xetpriority_msg[] = "cannot %cet priority";
-
int old_priority, adjustment;
- errno = 0; /* Needed for getpriority error detection. */
old_priority = getpriority(PRIO_PROCESS, 0);
- if (errno) {
- bb_perror_msg_and_die(Xetpriority_msg, 'g');
- }
if (!*++argv) { /* No args, so (GNU) output current nice value. */
bb_printf("%d\n", old_priority);
adjustment = 10; /* Set default adjustment. */
- if ((argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) { /* "-n" */
+ if (argv[0][0] == '-') {
+ if (argv[0][1] == 'n') { /* -n */
+ if (argv[0][2]) { /* -nNNNN (w/o space) */
+ argv[0] += 2; argv--; argc++;
+ }
+ } else { /* -NNN (NNN may be negative) == -n NNN */
+ argv[0] += 1; argv--; argc++;
+ }
if (argc < 4) { /* Missing priority and/or utility! */
bb_show_usage();
}
- adjustment = xatoi(argv[1]);
+ adjustment = xatoi_range(argv[1], INT_MIN/2, INT_MAX/2);
argv += 2;
}
- { /* Set our priority. Handle integer wrapping for old + adjust. */
- int new_priority = int_add_no_wrap(old_priority, adjustment);
+ { /* Set our priority. */
+ int prio = old_priority + adjustment;
- if (setpriority(PRIO_PROCESS, 0, new_priority) < 0) {
- bb_perror_msg_and_die(Xetpriority_msg, 's');
+ if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
+ bb_perror_msg_and_die("setpriority(%d)", prio);
}
}
#include "busybox.h"
#include <getopt.h>
+#include <sys/resource.h>
static int signal_nr = 15;
static int user_id = -1;
#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
static const struct option ssd_long_options[] = {
- { "stop", 0, NULL, 'K' },
- { "start", 0, NULL, 'S' },
- { "background", 0, NULL, 'b' },
- { "quiet", 0, NULL, 'q' },
- { "make-pidfile", 0, NULL, 'm' },
+ { "stop", 0, NULL, 'K' },
+ { "start", 0, NULL, 'S' },
+ { "background", 0, NULL, 'b' },
+ { "quiet", 0, NULL, 'q' },
+ { "make-pidfile", 0, NULL, 'm' },
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
- { "oknodo", 0, NULL, 'o' },
- { "verbose", 0, NULL, 'v' },
+ { "oknodo", 0, NULL, 'o' },
+ { "verbose", 0, NULL, 'v' },
+ { "nicelevel", 1, NULL, 'N' },
#endif
- { "startas", 1, NULL, 'a' },
- { "name", 1, NULL, 'n' },
- { "signal", 1, NULL, 's' },
- { "user", 1, NULL, 'u' },
- { "chuid", 1, NULL, 'c' },
- { "exec", 1, NULL, 'x' },
- { "pidfile", 1, NULL, 'p' },
+ { "startas", 1, NULL, 'a' },
+ { "name", 1, NULL, 'n' },
+ { "signal", 1, NULL, 's' },
+ { "user", 1, NULL, 'u' },
+ { "chuid", 1, NULL, 'c' },
+ { "exec", 1, NULL, 'x' },
+ { "pidfile", 1, NULL, 'p' },
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
- { "retry", 1, NULL, 'R' },
+ { "retry", 1, NULL, 'R' },
#endif
- { 0, 0, 0, 0 }
+ { 0, 0, 0, 0 }
};
#endif
-#define SSD_CTX_STOP 1
-#define SSD_CTX_START 2
-#define SSD_OPT_BACKGROUND 4
-#define SSD_OPT_QUIET 8
-#define SSD_OPT_MAKEPID 16
+#define SSD_CTX_STOP 0x1
+#define SSD_CTX_START 0x2
+#define SSD_OPT_BACKGROUND 0x4
+#define SSD_OPT_QUIET 0x8
+#define SSD_OPT_MAKEPID 0x10
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
-#define SSD_OPT_OKNODO 32
-#define SSD_OPT_VERBOSE 64
-
+#define SSD_OPT_OKNODO 0x20
+#define SSD_OPT_VERBOSE 0x40
+#define SSD_OPT_NICELEVEL 0x80
#endif
int start_stop_daemon_main(int argc, char **argv)
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
// char *retry_arg = NULL;
// int retries = -1;
+ char *opt_N;
#endif
#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
applet_long_options = ssd_long_options;
/* Check required one context option was given */
opt_complementary = "K:S:?:K--S:S--K:m?p:K?xpun:S?xa";
opt = getopt32(argc, argv, "KSbqm"
-// USE_FEATURE_START_STOP_DAEMON_FANCY("ovR:")
- USE_FEATURE_START_STOP_DAEMON_FANCY("ov")
+// USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:")
+ USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:")
"a:n:s:u:c:x:p:"
+ USE_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N)
// USE_FEATURE_START_STOP_DAEMON_FANCY(,&retry_arg)
,&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile);
if (found) {
if (!quiet)
- printf("%s already running.\n%d\n", execname ,found->pid);
+ printf("%s already running\n%d\n", execname, found->pid);
USE_FEATURE_START_STOP_DAEMON_FANCY(return !(opt & SSD_OPT_OKNODO);)
SKIP_FEATURE_START_STOP_DAEMON_FANCY(return EXIT_FAILURE;)
}
fprintf(pidf, "%d\n", pidt);
fclose(pidf);
}
- if(chuid) {
- if(sscanf(chuid, "%d", &user_id) != 1)
+ if (chuid) {
+ if (sscanf(chuid, "%d", &user_id) != 1)
user_id = bb_xgetpwnam(chuid);
- setuid(user_id);
+ xsetuid(user_id);
}
+#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
+ if (opt & SSD_OPT_NICELEVEL) {
+ /* Set process priority */
+ int prio = getpriority(PRIO_PROCESS, 0) + xatoi_range(opt_N, INT_MIN/2, INT_MAX/2);
+ if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
+ bb_perror_msg_and_die("setpriority(%d)", prio);
+ }
+ }
+#endif
execv(startas, argv);
bb_perror_msg_and_die ("unable to start %s", startas);
}
#error Assumption violated : PRIO_USER value
#endif
-static inline int int_add_no_wrap(int a, int b)
-{
- int s = a + b;
-
- if (b < 0) {
- if (s > a) s = INT_MIN;
- } else {
- if (s < a) s = INT_MAX;
- }
-
- return s;
-}
-
int renice_main(int argc, char **argv)
{
- static const char Xetpriority_msg[] = "%d: %cetpriority";
+ static const char Xetpriority_msg[] = "%cetpriority";
int retval = EXIT_SUCCESS;
int which = PRIO_PROCESS; /* Default 'which' value. */
int use_relative = 0;
int adjustment, new_priority;
unsigned who;
+ char *arg;
- ++argv;
+ arg = *++argv;
/* Check if we are using a relative adjustment. */
- if (argv[0] && (argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) {
+ if (arg && arg[0] == '-' && arg[1] == 'n') {
use_relative = 1;
- ++argv;
+ if (!arg[2])
+ arg = *++argv;
+ else
+ arg += 2;
}
- if (!*argv) { /* No args? Then show usage. */
+ if (!arg) { /* No args? Then show usage. */
bb_show_usage();
}
/* Get the priority adjustment (absolute or relative). */
- adjustment = xatoi(*argv);
+ adjustment = xatoi_range(arg, INT_MIN/2, INT_MAX/2);
- while (*++argv) {
+ while ((arg = *++argv) != NULL) {
/* Check for a mode switch. */
- if ((argv[0][0] == '-') && argv[0][1] && !argv[0][2]) {
+ if (arg[0] == '-' && arg[1]) {
static const char opts[]
= { 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER };
- const char *p = strchr(opts, argv[0][1]);
+ const char *p = strchr(opts, arg[1]);
if (p) {
which = p[4];
- continue;
+ if (!arg[2])
+ continue;
+ arg += 2;
}
}
/* Process an ID arg. */
if (which == PRIO_USER) {
struct passwd *p;
- p = getpwnam(*argv);
+ p = getpwnam(arg);
if (!p) {
- bb_error_msg("unknown user: %s", *argv);
+ bb_error_msg("unknown user: %s", arg);
goto HAD_ERROR;
}
who = p->pw_uid;
} else {
- if (safe_strtou(*argv, &who)) {
- bb_error_msg("bad value: %s", *argv);
+ if (safe_strtou(arg, &who)) {
+ bb_error_msg("bad value: %s", arg);
goto HAD_ERROR;
}
}
errno = 0; /* Needed for getpriority error detection. */
old_priority = getpriority(which, who);
if (errno) {
- bb_perror_msg(Xetpriority_msg, who, 'g');
+ bb_perror_msg(Xetpriority_msg, 'g');
goto HAD_ERROR;
}
- new_priority = int_add_no_wrap(old_priority, adjustment);
+ new_priority = old_priority + adjustment;
} else {
new_priority = adjustment;
}
continue;
}
- bb_perror_msg(Xetpriority_msg, who, 's');
- HAD_ERROR:
+ bb_perror_msg(Xetpriority_msg, 's');
+ HAD_ERROR:
retval = EXIT_FAILURE;
}