mirror of
https://github.com/topjohnwu/ndk-busybox.git
synced 2024-11-25 04:39:48 +00:00
start_stop_daemon: add -N <nice> compat
[re]nice: add support for -nNNN w/o spaces, -NNN (nice only), simplified code
This commit is contained in:
parent
7039a66b58
commit
ca3c981c07
@ -7,39 +7,14 @@
|
|||||||
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
* 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 <sys/resource.h>
|
||||||
#include "busybox.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)
|
int nice_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static const char Xetpriority_msg[] = "cannot %cet priority";
|
|
||||||
|
|
||||||
int old_priority, adjustment;
|
int old_priority, adjustment;
|
||||||
|
|
||||||
errno = 0; /* Needed for getpriority error detection. */
|
|
||||||
old_priority = getpriority(PRIO_PROCESS, 0);
|
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. */
|
if (!*++argv) { /* No args, so (GNU) output current nice value. */
|
||||||
bb_printf("%d\n", old_priority);
|
bb_printf("%d\n", old_priority);
|
||||||
@ -48,19 +23,26 @@ int nice_main(int argc, char **argv)
|
|||||||
|
|
||||||
adjustment = 10; /* Set default adjustment. */
|
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! */
|
if (argc < 4) { /* Missing priority and/or utility! */
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
}
|
}
|
||||||
adjustment = xatoi(argv[1]);
|
adjustment = xatoi_range(argv[1], INT_MIN/2, INT_MAX/2);
|
||||||
argv += 2;
|
argv += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ /* Set our priority. Handle integer wrapping for old + adjust. */
|
{ /* Set our priority. */
|
||||||
int new_priority = int_add_no_wrap(old_priority, adjustment);
|
int prio = old_priority + adjustment;
|
||||||
|
|
||||||
if (setpriority(PRIO_PROCESS, 0, new_priority) < 0) {
|
if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
|
||||||
bb_perror_msg_and_die(Xetpriority_msg, 's');
|
bb_perror_msg_and_die("setpriority(%d)", prio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
static int signal_nr = 15;
|
static int signal_nr = 15;
|
||||||
static int user_id = -1;
|
static int user_id = -1;
|
||||||
@ -191,38 +192,39 @@ static int do_stop(void)
|
|||||||
|
|
||||||
#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
|
#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
|
||||||
static const struct option ssd_long_options[] = {
|
static const struct option ssd_long_options[] = {
|
||||||
{ "stop", 0, NULL, 'K' },
|
{ "stop", 0, NULL, 'K' },
|
||||||
{ "start", 0, NULL, 'S' },
|
{ "start", 0, NULL, 'S' },
|
||||||
{ "background", 0, NULL, 'b' },
|
{ "background", 0, NULL, 'b' },
|
||||||
{ "quiet", 0, NULL, 'q' },
|
{ "quiet", 0, NULL, 'q' },
|
||||||
{ "make-pidfile", 0, NULL, 'm' },
|
{ "make-pidfile", 0, NULL, 'm' },
|
||||||
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
|
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
|
||||||
{ "oknodo", 0, NULL, 'o' },
|
{ "oknodo", 0, NULL, 'o' },
|
||||||
{ "verbose", 0, NULL, 'v' },
|
{ "verbose", 0, NULL, 'v' },
|
||||||
|
{ "nicelevel", 1, NULL, 'N' },
|
||||||
#endif
|
#endif
|
||||||
{ "startas", 1, NULL, 'a' },
|
{ "startas", 1, NULL, 'a' },
|
||||||
{ "name", 1, NULL, 'n' },
|
{ "name", 1, NULL, 'n' },
|
||||||
{ "signal", 1, NULL, 's' },
|
{ "signal", 1, NULL, 's' },
|
||||||
{ "user", 1, NULL, 'u' },
|
{ "user", 1, NULL, 'u' },
|
||||||
{ "chuid", 1, NULL, 'c' },
|
{ "chuid", 1, NULL, 'c' },
|
||||||
{ "exec", 1, NULL, 'x' },
|
{ "exec", 1, NULL, 'x' },
|
||||||
{ "pidfile", 1, NULL, 'p' },
|
{ "pidfile", 1, NULL, 'p' },
|
||||||
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
|
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
|
||||||
{ "retry", 1, NULL, 'R' },
|
{ "retry", 1, NULL, 'R' },
|
||||||
#endif
|
#endif
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SSD_CTX_STOP 1
|
#define SSD_CTX_STOP 0x1
|
||||||
#define SSD_CTX_START 2
|
#define SSD_CTX_START 0x2
|
||||||
#define SSD_OPT_BACKGROUND 4
|
#define SSD_OPT_BACKGROUND 0x4
|
||||||
#define SSD_OPT_QUIET 8
|
#define SSD_OPT_QUIET 0x8
|
||||||
#define SSD_OPT_MAKEPID 16
|
#define SSD_OPT_MAKEPID 0x10
|
||||||
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
|
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
|
||||||
#define SSD_OPT_OKNODO 32
|
#define SSD_OPT_OKNODO 0x20
|
||||||
#define SSD_OPT_VERBOSE 64
|
#define SSD_OPT_VERBOSE 0x40
|
||||||
|
#define SSD_OPT_NICELEVEL 0x80
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int start_stop_daemon_main(int argc, char **argv)
|
int start_stop_daemon_main(int argc, char **argv)
|
||||||
@ -233,6 +235,7 @@ int start_stop_daemon_main(int argc, char **argv)
|
|||||||
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
|
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
|
||||||
// char *retry_arg = NULL;
|
// char *retry_arg = NULL;
|
||||||
// int retries = -1;
|
// int retries = -1;
|
||||||
|
char *opt_N;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
|
#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
|
||||||
applet_long_options = ssd_long_options;
|
applet_long_options = ssd_long_options;
|
||||||
@ -241,9 +244,10 @@ int start_stop_daemon_main(int argc, char **argv)
|
|||||||
/* Check required one context option was given */
|
/* Check required one context option was given */
|
||||||
opt_complementary = "K:S:?:K--S:S--K:m?p:K?xpun:S?xa";
|
opt_complementary = "K:S:?:K--S:S--K:m?p:K?xpun:S?xa";
|
||||||
opt = getopt32(argc, argv, "KSbqm"
|
opt = getopt32(argc, argv, "KSbqm"
|
||||||
// USE_FEATURE_START_STOP_DAEMON_FANCY("ovR:")
|
// USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:")
|
||||||
USE_FEATURE_START_STOP_DAEMON_FANCY("ov")
|
USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:")
|
||||||
"a:n:s:u:c:x:p:"
|
"a:n:s:u:c:x:p:"
|
||||||
|
USE_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N)
|
||||||
// USE_FEATURE_START_STOP_DAEMON_FANCY(,&retry_arg)
|
// USE_FEATURE_START_STOP_DAEMON_FANCY(,&retry_arg)
|
||||||
,&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile);
|
,&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile);
|
||||||
|
|
||||||
@ -279,7 +283,7 @@ int start_stop_daemon_main(int argc, char **argv)
|
|||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
if (!quiet)
|
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);)
|
USE_FEATURE_START_STOP_DAEMON_FANCY(return !(opt & SSD_OPT_OKNODO);)
|
||||||
SKIP_FEATURE_START_STOP_DAEMON_FANCY(return EXIT_FAILURE;)
|
SKIP_FEATURE_START_STOP_DAEMON_FANCY(return EXIT_FAILURE;)
|
||||||
}
|
}
|
||||||
@ -296,11 +300,20 @@ int start_stop_daemon_main(int argc, char **argv)
|
|||||||
fprintf(pidf, "%d\n", pidt);
|
fprintf(pidf, "%d\n", pidt);
|
||||||
fclose(pidf);
|
fclose(pidf);
|
||||||
}
|
}
|
||||||
if(chuid) {
|
if (chuid) {
|
||||||
if(sscanf(chuid, "%d", &user_id) != 1)
|
if (sscanf(chuid, "%d", &user_id) != 1)
|
||||||
user_id = bb_xgetpwnam(chuid);
|
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);
|
execv(startas, argv);
|
||||||
bb_perror_msg_and_die ("unable to start %s", startas);
|
bb_perror_msg_and_die ("unable to start %s", startas);
|
||||||
}
|
}
|
||||||
|
@ -346,6 +346,7 @@ long xatol_sfx(const char *numstr, const struct suffix_mult *suffixes);
|
|||||||
long xatol(const char *numstr);
|
long xatol(const char *numstr);
|
||||||
/* Specialized: */
|
/* Specialized: */
|
||||||
unsigned xatou(const char *numstr);
|
unsigned xatou(const char *numstr);
|
||||||
|
int xatoi_range(const char *numstr, int lower, int upper);
|
||||||
int xatoi(const char *numstr);
|
int xatoi(const char *numstr);
|
||||||
/* Using xatoi() instead of naive atoi() is not always convenient -
|
/* Using xatoi() instead of naive atoi() is not always convenient -
|
||||||
* in many places people want *non-negative* values, but store them
|
* in many places people want *non-negative* values, but store them
|
||||||
|
@ -2691,6 +2691,7 @@ USE_FEATURE_MDEV_CONFIG( \
|
|||||||
USE_FEATURE_START_STOP_DAEMON_FANCY( \
|
USE_FEATURE_START_STOP_DAEMON_FANCY( \
|
||||||
"\n\t-o|--oknodo\t\t\texit status 0 if nothing done" \
|
"\n\t-o|--oknodo\t\t\texit status 0 if nothing done" \
|
||||||
"\n\t-v|--verbose\t\t\tbe verbose" \
|
"\n\t-v|--verbose\t\t\tbe verbose" \
|
||||||
|
"\n\t-N|--nicelevel <N>\t\tadd N to process's nice level" \
|
||||||
) \
|
) \
|
||||||
"\n\t-s|--signal <signal>\t\tsignal to send (default TERM)" \
|
"\n\t-s|--signal <signal>\t\tsignal to send (default TERM)" \
|
||||||
"\n\t-U|--chuid <username>|<uid>\tstart process with this name"
|
"\n\t-U|--chuid <username>|<uid>\tstart process with this name"
|
||||||
|
@ -189,6 +189,11 @@ unsigned xatou(const char *numstr)
|
|||||||
return xatoul_range(numstr, 0, UINT_MAX);
|
return xatoul_range(numstr, 0, UINT_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xatoi_range(const char *numstr, int lower, int upper)
|
||||||
|
{
|
||||||
|
return xatol_range(numstr, lower, upper);
|
||||||
|
}
|
||||||
|
|
||||||
int xatoi(const char *numstr)
|
int xatoi(const char *numstr)
|
||||||
{
|
{
|
||||||
return xatol_range(numstr, INT_MIN, INT_MAX);
|
return xatol_range(numstr, INT_MIN, INT_MAX);
|
||||||
|
@ -38,68 +38,61 @@
|
|||||||
#error Assumption violated : PRIO_USER value
|
#error Assumption violated : PRIO_USER value
|
||||||
#endif
|
#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)
|
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 retval = EXIT_SUCCESS;
|
||||||
int which = PRIO_PROCESS; /* Default 'which' value. */
|
int which = PRIO_PROCESS; /* Default 'which' value. */
|
||||||
int use_relative = 0;
|
int use_relative = 0;
|
||||||
int adjustment, new_priority;
|
int adjustment, new_priority;
|
||||||
unsigned who;
|
unsigned who;
|
||||||
|
char *arg;
|
||||||
|
|
||||||
++argv;
|
arg = *++argv;
|
||||||
|
|
||||||
/* Check if we are using a relative adjustment. */
|
/* 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;
|
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();
|
bb_show_usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the priority adjustment (absolute or relative). */
|
/* 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. */
|
/* Check for a mode switch. */
|
||||||
if ((argv[0][0] == '-') && argv[0][1] && !argv[0][2]) {
|
if (arg[0] == '-' && arg[1]) {
|
||||||
static const char opts[]
|
static const char opts[]
|
||||||
= { 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER };
|
= { '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) {
|
if (p) {
|
||||||
which = p[4];
|
which = p[4];
|
||||||
continue;
|
if (!arg[2])
|
||||||
|
continue;
|
||||||
|
arg += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process an ID arg. */
|
/* Process an ID arg. */
|
||||||
if (which == PRIO_USER) {
|
if (which == PRIO_USER) {
|
||||||
struct passwd *p;
|
struct passwd *p;
|
||||||
p = getpwnam(*argv);
|
p = getpwnam(arg);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
bb_error_msg("unknown user: %s", *argv);
|
bb_error_msg("unknown user: %s", arg);
|
||||||
goto HAD_ERROR;
|
goto HAD_ERROR;
|
||||||
}
|
}
|
||||||
who = p->pw_uid;
|
who = p->pw_uid;
|
||||||
} else {
|
} else {
|
||||||
if (safe_strtou(*argv, &who)) {
|
if (safe_strtou(arg, &who)) {
|
||||||
bb_error_msg("bad value: %s", *argv);
|
bb_error_msg("bad value: %s", arg);
|
||||||
goto HAD_ERROR;
|
goto HAD_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,11 +104,11 @@ int renice_main(int argc, char **argv)
|
|||||||
errno = 0; /* Needed for getpriority error detection. */
|
errno = 0; /* Needed for getpriority error detection. */
|
||||||
old_priority = getpriority(which, who);
|
old_priority = getpriority(which, who);
|
||||||
if (errno) {
|
if (errno) {
|
||||||
bb_perror_msg(Xetpriority_msg, who, 'g');
|
bb_perror_msg(Xetpriority_msg, 'g');
|
||||||
goto HAD_ERROR;
|
goto HAD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_priority = int_add_no_wrap(old_priority, adjustment);
|
new_priority = old_priority + adjustment;
|
||||||
} else {
|
} else {
|
||||||
new_priority = adjustment;
|
new_priority = adjustment;
|
||||||
}
|
}
|
||||||
@ -124,8 +117,8 @@ int renice_main(int argc, char **argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb_perror_msg(Xetpriority_msg, who, 's');
|
bb_perror_msg(Xetpriority_msg, 's');
|
||||||
HAD_ERROR:
|
HAD_ERROR:
|
||||||
retval = EXIT_FAILURE;
|
retval = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user