1 /*
2 * renice - set system scheduling priorities of running processes
3 *
4 * Gunnar Ritter, Freiburg i. Br., Germany, August 2002.
5 */
6 /*
7 * Copyright (c) 2003 Gunnar Ritter
8 *
9 * This software is provided 'as-is', without any express or implied
10 * warranty. In no event will the authors be held liable for any damages
11 * arising from the use of this software.
12 *
13 * Permission is granted to anyone to use this software for any purpose,
14 * including commercial applications, and to alter it and redistribute
15 * it freely, subject to the following restrictions:
16 *
17 * 1. The origin of this software must not be misrepresented; you must not
18 * claim that you wrote the original software. If you use this software
19 * in a product, an acknowledgment in the product documentation would be
20 * appreciated but is not required.
21 *
22 * 2. Altered source versions must be plainly marked as such, and must not be
23 * misrepresented as being the original software.
24 *
25 * 3. This notice may not be removed or altered from any source distribution.
26 */
27
28 #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4
29 #define USED __attribute__ ((used))
30 #elif defined __GNUC__
31 #define USED __attribute__ ((unused))
32 #else
33 #define USED
34 #endif
35 static const char sccsid[] USED = "@(#)renice.sl 1.7 (gritter) 5/29/05";
36
37 #include <sys/time.h>
38 #include <sys/resource.h>
39 #include <unistd.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdlib.h>
43 #include <errno.h>
44 #include <libgen.h>
45 #include <pwd.h>
46
47 #ifndef PRIO_MIN
48 #define PRIO_MIN -20
49 #endif
50 #ifndef PRIO_MAX
51 #define PRIO_MAX 20
52 #endif
53
54 unsigned errcnt; /* count of errors */
55 char *progname; /* argv[0] to main() */
56 int selection; /* one of '\0' 'g' 'p' 'i' */
57
58 int traditional_donice(int which, int who, int prio);
59 int traditional_renice(int argc, char **argv);
60
61 void
usage(void)62 usage(void)
63 {
64 fprintf(stderr, "\
65 usage: %s priority [ [ -p ] pids ] [ [ -g ] pgrps ] [ [ -u ] users ]\n\
66 %s [ -n increment ] [-g | -p | -u ] ID\n",
67 progname, progname);
68 exit(2);
69 }
70
71 int
main(int argc,char ** argv)72 main(int argc, char **argv)
73 {
74 struct passwd *pwd;
75 char *x;
76 int i, which = 0, who = 0, oldval;
77 int increment = 10;
78
79 #ifdef __GLIBC__
80 putenv("POSIXLY_CORRECT=1");
81 #endif
82 progname = basename(argv[0]);
83 if (argc > 1) {
84 i = strtol(argv[1], &x, 10);
85 if (*x == '\0' && i >= -20 && i <= 20)
86 return traditional_renice(argc, argv);
87 }
88 while ((i = getopt(argc, argv, "gn:pu")) != EOF) {
89 switch (i) {
90 case 'g':
91 case 'p':
92 case 'u':
93 if (selection != '\0')
94 usage();
95 selection = i;
96 break;
97 case 'n':
98 increment = strtol(optarg, &x, 10);
99 if (*x != '\0')
100 usage();
101 break;
102 default:
103 usage();
104 }
105 }
106 if (optind >= argc)
107 usage();
108 for ( ; optind < argc; optind++) {
109 switch (selection) {
110 case '\0':
111 case 'g':
112 case 'p':
113 which = (selection == 'g' ? PRIO_PGRP : PRIO_PROCESS);
114 who = strtol(argv[optind], &x, 10);
115 if (*x != '\0') {
116 fprintf(stderr, "%s: bad value: %s\n",
117 progname, argv[optind]);
118 errcnt |= 1;
119 continue;
120 }
121 break;
122 case 'u':
123 which = PRIO_USER;
124 if ((pwd = getpwnam(argv[optind])) != NULL) {
125 who = pwd->pw_uid;
126 } else {
127 who = strtol(argv[optind], &x, 10);
128 if (*x != '\0') {
129 fprintf(stderr,
130 "%s: unknown user: %s\n",
131 progname, argv[optind]);
132 continue;
133 }
134 }
135 break;
136 }
137 errno = 0;
138 if ((oldval = getpriority(which, who)) == -1 && errno != 0) {
139 fprintf(stderr, "%s: %d:getpriority: %s\n", progname,
140 who, strerror(errno));
141 errcnt |= 1;
142 continue;
143 }
144 if (setpriority(which, who, oldval + increment) < 0) {
145 fprintf(stderr, "%s: %d:setpriority: %s\n", progname,
146 who, strerror(errno));
147 errcnt |= 1;
148 continue;
149 }
150 }
151 return errcnt;
152 }
153
154 /*
155 * Copyright (c) 1980 Regents of the University of California.
156 * All rights reserved. The Berkeley software License Agreement
157 * specifies the terms and conditions for redistribution.
158 *
159 * Redistribution and use in source and binary forms, with or without
160 * modification, are permitted provided that the following conditions
161 * are met:
162 * 1. Redistributions of source code must retain the above copyright
163 * notice, this list of conditions and the following disclaimer.
164 * 2. Redistributions in binary form must reproduce the above copyright
165 * notice, this list of conditions and the following disclaimer in the
166 * documentation and/or other materials provided with the distribution.
167 * 3. All advertising materials mentioning features or use of this software
168 * must display the following acknowledgement:
169 * This product includes software developed by the University of
170 * California, Berkeley and its contributors.
171 * 4. Neither the name of the University nor the names of its contributors
172 * may be used to endorse or promote products derived from this software
173 * without specific prior written permission.
174 *
175 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
176 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
177 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
178 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
179 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
180 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
181 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
182 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
183 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
184 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
185 * SUCH DAMAGE.
186 *
187 * from 4.3BSD Tahoe renice.c 5.1 (Berkeley) 5/28/85
188 */
189
190 /*
191 * Change the priority (nice) of processes
192 * or groups of processes which are already
193 * running.
194 */
195 int
traditional_renice(int argc,char ** argv)196 traditional_renice(int argc, char **argv)
197 {
198 int which = PRIO_PROCESS;
199 int who = 0, prio, errs = 0;
200
201 argc--, argv++;
202 if (argc < 2)
203 usage();
204 prio = atoi(*argv);
205 argc--, argv++;
206 if (prio > PRIO_MAX)
207 prio = PRIO_MAX;
208 if (prio < PRIO_MIN)
209 prio = PRIO_MIN;
210 for (; argc > 0; argc--, argv++) {
211 if (strcmp(*argv, "-g") == 0) {
212 which = PRIO_PGRP;
213 continue;
214 }
215 if (strcmp(*argv, "-u") == 0) {
216 which = PRIO_USER;
217 continue;
218 }
219 if (strcmp(*argv, "-p") == 0) {
220 which = PRIO_PROCESS;
221 continue;
222 }
223 if (which == PRIO_USER) {
224 register struct passwd *pwd = getpwnam(*argv);
225
226 if (pwd == NULL) {
227 fprintf(stderr, "renice: %s: unknown user\n",
228 *argv);
229 continue;
230 }
231 who = pwd->pw_uid;
232 } else {
233 who = atoi(*argv);
234 if (who < 0) {
235 fprintf(stderr, "renice: %s: bad value\n",
236 *argv);
237 continue;
238 }
239 }
240 errs += traditional_donice(which, who, prio);
241 }
242 return errs != 0;
243 }
244
245 int
traditional_donice(int which,int who,int prio)246 traditional_donice(int which, int who, int prio)
247 {
248 int oldprio;
249
250 errno = 0, oldprio = getpriority(which, who);
251 if (oldprio == -1 && errno) {
252 fprintf(stderr, "renice: %d: ", who);
253 perror("getpriority");
254 return 1;
255 }
256 if (setpriority(which, who, prio) < 0) {
257 fprintf(stderr, "renice: %d: ", who);
258 perror("setpriority");
259 return 1;
260 }
261 printf("%d: old priority %d, new priority %d\n", who, oldprio, prio);
262 return 0;
263 }
264