aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2005-02-13 20:14:05 +0000
committerManuel Novoa III <mjn3@codepoet.org>2005-02-13 20:14:05 +0000
commit2c511609c4d92ee4e3e603d449c13579d1ea641a (patch)
treed57c8dd9efa4c30cd01290f878cae688ae792cc0
parentd2fe81706c9d65dd1580c85338036cc403364fae (diff)
downloadbusybox-w32-2c511609c4d92ee4e3e603d449c13579d1ea641a.tar.gz
busybox-w32-2c511609c4d92ee4e3e603d449c13579d1ea641a.tar.bz2
busybox-w32-2c511609c4d92ee4e3e603d449c13579d1ea641a.zip
Add 'nice' and replace 'renice' with a new implementation.
-rw-r--r--AUTHORS3
-rw-r--r--coreutils/Config.in6
-rw-r--r--coreutils/Makefile.in1
-rw-r--r--coreutils/nice.c86
-rw-r--r--include/applets.h3
-rw-r--r--include/usage.h18
-rw-r--r--procps/renice.c132
7 files changed, 227 insertions, 22 deletions
diff --git a/AUTHORS b/AUTHORS
index 2bce2e849..6e29eed54 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -88,7 +88,8 @@ Glenn McGrath <bug1@iinet.net.au>
88 88
89Manuel Novoa III <mjn3@codepoet.org> 89Manuel Novoa III <mjn3@codepoet.org>
90 cat, head, mkfifo, mknod, rmdir, sleep, tee, tty, uniq, usleep, wc, yes, 90 cat, head, mkfifo, mknod, rmdir, sleep, tee, tty, uniq, usleep, wc, yes,
91 mesg, vconfig, make_directory, parse_mode, dirname, mode_string, 91 mesg, vconfig, nice, renice,
92 make_directory, parse_mode, dirname, mode_string,
92 get_last_path_component, simplify_path, and a number trivial libbb routines 93 get_last_path_component, simplify_path, and a number trivial libbb routines
93 94
94 also bug fixes, partial rewrites, and size optimizations in 95 also bug fixes, partial rewrites, and size optimizations in
diff --git a/coreutils/Config.in b/coreutils/Config.in
index 4aff5ce69..a299506e6 100644
--- a/coreutils/Config.in
+++ b/coreutils/Config.in
@@ -329,6 +329,12 @@ config CONFIG_MV
329 help 329 help
330 mv is used to move or rename files or directories. 330 mv is used to move or rename files or directories.
331 331
332config CONFIG_NICE
333 bool "nice"
334 default n
335 help
336 nice runs a program with modified scheduling priority.
337
332config CONFIG_OD 338config CONFIG_OD
333 bool "od" 339 bool "od"
334 default n 340 default n
diff --git a/coreutils/Makefile.in b/coreutils/Makefile.in
index aacb813b3..63823657f 100644
--- a/coreutils/Makefile.in
+++ b/coreutils/Makefile.in
@@ -58,6 +58,7 @@ COREUTILS-$(CONFIG_MKDIR) += mkdir.o
58COREUTILS-$(CONFIG_MKFIFO) += mkfifo.o 58COREUTILS-$(CONFIG_MKFIFO) += mkfifo.o
59COREUTILS-$(CONFIG_MKNOD) += mknod.o 59COREUTILS-$(CONFIG_MKNOD) += mknod.o
60COREUTILS-$(CONFIG_MV) += mv.o 60COREUTILS-$(CONFIG_MV) += mv.o
61COREUTILS-$(CONFIG_NICE) += nice.o
61COREUTILS-$(CONFIG_OD) += od.o 62COREUTILS-$(CONFIG_OD) += od.o
62COREUTILS-$(CONFIG_PRINTF) += printf.o 63COREUTILS-$(CONFIG_PRINTF) += printf.o
63COREUTILS-$(CONFIG_PWD) += pwd.o 64COREUTILS-$(CONFIG_PWD) += pwd.o
diff --git a/coreutils/nice.c b/coreutils/nice.c
new file mode 100644
index 000000000..b66f9d82d
--- /dev/null
+++ b/coreutils/nice.c
@@ -0,0 +1,86 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * nice implementation for busybox
4 *
5 * Copyright (C) 2005 Manuel Novoa III <mjn3@codepoet.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <limits.h>
27#include <errno.h>
28#include <unistd.h>
29#include <sys/time.h>
30#include <sys/resource.h>
31#include "busybox.h"
32
33static inline int int_add_no_wrap(int a, int b)
34{
35 int s = a + b;
36
37 if (b < 0) {
38 if (s > a) s = INT_MIN;
39 } else {
40 if (s < a) s = INT_MAX;
41 }
42
43 return s;
44}
45
46int nice_main(int argc, char **argv)
47{
48 static const char Xetpriority_msg[] = "cannot %cet priority";
49
50 int old_priority, adjustment;
51
52 errno = 0; /* Needed for getpriority error detection. */
53 old_priority = getpriority(PRIO_PROCESS, 0);
54 if (errno) {
55 bb_perror_msg_and_die(Xetpriority_msg, 'g');
56 }
57
58 if (!*++argv) { /* No args, so (GNU) output current nice value. */
59 bb_printf("%d\n", old_priority);
60 bb_fflush_stdout_and_exit(EXIT_SUCCESS);
61 }
62
63 adjustment = 10; /* Set default adjustment. */
64
65 if ((argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) { /* "-n" */
66 if (argc < 4) { /* Missing priority and/or utility! */
67 bb_show_usage();
68 }
69 adjustment = bb_xgetlarg(argv[1], 10, INT_MIN, INT_MAX);
70 argv += 2;
71 }
72
73 { /* Set our priority. Handle integer wrapping for old + adjust. */
74 int new_priority = int_add_no_wrap(old_priority, adjustment);
75
76 if (setpriority(PRIO_PROCESS, 0, new_priority) < 0) {
77 bb_perror_msg_and_die(Xetpriority_msg, 's');
78 }
79 }
80
81 execvp(*argv, argv); /* Now exec the desired program. */
82
83 /* The exec failed... */
84 bb_default_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */
85 bb_perror_msg_and_die("%s", *argv);
86}
diff --git a/include/applets.h b/include/applets.h
index 90d4195cc..125703216 100644
--- a/include/applets.h
+++ b/include/applets.h
@@ -412,6 +412,9 @@
412#ifdef CONFIG_NETSTAT 412#ifdef CONFIG_NETSTAT
413 APPLET(netstat, netstat_main, _BB_DIR_BIN, _BB_SUID_NEVER) 413 APPLET(netstat, netstat_main, _BB_DIR_BIN, _BB_SUID_NEVER)
414#endif 414#endif
415#ifdef CONFIG_NICE
416 APPLET(nice, nice_main, _BB_DIR_BIN, _BB_SUID_NEVER)
417#endif
415#ifdef CONFIG_NSLOOKUP 418#ifdef CONFIG_NSLOOKUP
416 APPLET(nslookup, nslookup_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) 419 APPLET(nslookup, nslookup_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
417#endif 420#endif
diff --git a/include/usage.h b/include/usage.h
index c53ead0c7..fd0f68166 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -1813,6 +1813,13 @@
1813 "\t-w raw sockets\n" \ 1813 "\t-w raw sockets\n" \
1814 "\t-x unix sockets" 1814 "\t-x unix sockets"
1815 1815
1816#define nice_trivial_usage \
1817 "[-n ADJUST] [COMMAND [ARG] ...]"
1818#define nice_full_usage \
1819 "Nice runs a program with modified scheduling priority.\n\n" \
1820 "Options:\n" \
1821 "\t-n ADJUST\tAdjust the scheduling priority by ADJUST.\n" \
1822
1816#define nslookup_trivial_usage \ 1823#define nslookup_trivial_usage \
1817 "[HOST] [SERVER]" 1824 "[HOST] [SERVER]"
1818#define nslookup_full_usage \ 1825#define nslookup_full_usage \
@@ -2011,11 +2018,14 @@
2011 "\t-d\t\tdelay interval for rebooting." 2018 "\t-d\t\tdelay interval for rebooting."
2012 2019
2013#define renice_trivial_usage \ 2020#define renice_trivial_usage \
2014 "priority pid [pid ...]" 2021 "{{-n INCREMENT} | PRIORITY} [[ -p | -g | -u ] ID ...]"
2015#define renice_full_usage \ 2022#define renice_full_usage \
2016 "Changes priority of running processes. Allowed priorities range\n" \ 2023 "Changes priority of running processes.\n\n" \
2017 "from 20 (the process runs only when nothing else is running) to 0\n" \ 2024 "Options:\n" \
2018 "(default priority) to -20 (almost nothing else ever gets to run)." 2025 "\t-n\tadjusts current nice value (smaller is faster)\n" \
2026 "\t-p\tprocess id(s) (default)\n" \
2027 "\t-g\tprocess group id(s)\n" \
2028 "\t-u\tprocess user name(s) and/or id(s)"
2019 2029
2020#define reset_trivial_usage \ 2030#define reset_trivial_usage \
2021 "" 2031 ""
diff --git a/procps/renice.c b/procps/renice.c
index a6f0820df..d4ce66d2e 100644
--- a/procps/renice.c
+++ b/procps/renice.c
@@ -1,8 +1,8 @@
1/* vi: set sw=4 ts=4: */
1/* 2/*
2 * Mini renice implementation for busybox 3 * renice implementation for busybox
3 * 4 *
4 * 5 * Copyright (C) 2005 Manuel Novoa III <mjn3@codepoet.org>
5 * Copyright (C) 2000 Dave 'Kill a Cop' Cinege <dcinege@psychosis.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -20,35 +20,133 @@
20 * 20 *
21 */ 21 */
22 22
23/* Notes:
24 * Setting an absolute priority was obsoleted in SUSv2 and removed
25 * in SUSv3. However, the common linux version of renice does
26 * absolute and not relative. So we'll continue supporting absolute,
27 * although the stdout logging has been removed since both SUSv2 and
28 * SUSv3 specify that stdout isn't used.
29 *
30 * This version is lenient in that it doesn't require any IDs. The
31 * options -p, -g, and -u are treated as mode switches for the
32 * following IDs (if any). Multiple switches are allowed.
33 */
34
23#include <stdio.h> 35#include <stdio.h>
24#include <errno.h>
25#include <stdlib.h> 36#include <stdlib.h>
37#include <string.h>
38#include <limits.h>
39#include <errno.h>
40#include <unistd.h>
26#include <sys/time.h> 41#include <sys/time.h>
27#include <sys/resource.h> 42#include <sys/resource.h>
28#include "busybox.h" 43#include "busybox.h"
29 44
45#if (PRIO_PROCESS < CHAR_MIN) || (PRIO_PROCESS > CHAR_MAX)
46#error Assumption violated : PRIO_PROCESS value
47#endif
48#if (PRIO_PGRP < CHAR_MIN) || (PRIO_PGRP > CHAR_MAX)
49#error Assumption violated : PRIO_PGRP value
50#endif
51#if (PRIO_USER < CHAR_MIN) || (PRIO_USER > CHAR_MAX)
52#error Assumption violated : PRIO_USER value
53#endif
54
55static inline int int_add_no_wrap(int a, int b)
56{
57 int s = a + b;
58
59 if (b < 0) {
60 if (s > a) s = INT_MIN;
61 } else {
62 if (s < a) s = INT_MAX;
63 }
30 64
31extern int renice_main(int argc, char **argv) 65 return s;
66}
67
68int renice_main(int argc, char **argv)
32{ 69{
33 int prio, status = EXIT_SUCCESS; 70 static const char Xetpriority_msg[] = "%d : %cetpriority";
71
72 int retval = EXIT_SUCCESS;
73 int which = PRIO_PROCESS; /* Default 'which' value. */
74 int use_relative = 0;
75 int adjustment, new_priority;
76 id_t who;
34 77
35 if (argc < 3) bb_show_usage(); 78 ++argv;
36 79
37 prio = atoi(*++argv); 80 /* Check if we are using a relative adjustment. */
38 if (prio > 20) prio = 20; 81 if (argv[0] && (argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) {
39 if (prio < -20) prio = -20; 82 use_relative = 1;
83 ++argv;
84 }
85
86 if (!*argv) { /* No args? Then show usage. */
87 bb_show_usage();
88 }
89
90 /* Get the priority adjustment (absolute or relative). */
91 adjustment = bb_xgetlarg(*argv, 10, INT_MIN, INT_MAX);
40 92
41 while (*++argv) { 93 while (*++argv) {
42 int ps = atoi(*argv); 94 /* Check for a mode switch. */
43 int oldp = getpriority(PRIO_PROCESS, ps); 95 if ((argv[0][0] == '-') && argv[0][1] && !argv[0][2]) {
96 static const char opts[]
97 = { 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER };
98 const char *p;
99 if ((p = strchr(opts, argv[0][1]))) {
100 which = p[4];
101 continue;
102 }
103 }
44 104
45 if (setpriority(PRIO_PROCESS, ps, prio) == 0) { 105 /* Process an ID arg. */
46 printf("%d: old priority %d, new priority %d\n", ps, oldp, prio ); 106 if (which == PRIO_USER) {
107 struct passwd *p;
108 if (!(p = getpwnam(*argv))) {
109 bb_error_msg("unknown user: %s", *argv);
110 goto HAD_ERROR;
111 }
112 who = p->pw_uid;
47 } else { 113 } else {
48 bb_perror_msg("%d: setpriority", ps); 114 char *e;
49 status = EXIT_FAILURE; 115 errno = 0;
116 who = strtoul(*argv, &e, 10);
117 if (*e || (*argv == e) || errno) {
118 bb_error_msg("bad value: %s", *argv);
119 goto HAD_ERROR;
120 }
50 } 121 }
122
123 /* Get priority to use, and set it. */
124 if (use_relative) {
125 int old_priority;
126
127 errno = 0; /* Needed for getpriority error detection. */
128 old_priority = getpriority(which, who);
129 if (errno) {
130 bb_perror_msg(Xetpriority_msg, who, 'g');
131 goto HAD_ERROR;
132 }
133
134 new_priority = int_add_no_wrap(old_priority, adjustment);
135 } else {
136 new_priority = adjustment;
137 }
138
139 if (setpriority(which, who, new_priority) == 0) {
140 continue;
141 }
142
143 bb_perror_msg(Xetpriority_msg, who, 's');
144 HAD_ERROR:
145 retval = EXIT_FAILURE;
51 } 146 }
52 147
53 return status; 148 /* No need to check for errors outputing to stderr since, if it
149 * was used, the HAD_ERROR label was reached and retval was set. */
150
151 return retval;
54} 152}