4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 * University Copyright- Copyright (c) 1982, 1986, 1988
31 * The Regents of the University of California
34 * University Acknowledgment- Portions of this document are derived from
35 * software developed by the University of California, Berkeley, and its
39 #pragma ident "%Z%%M% %I% %E% SMI"
41 #include <sys/types.h>
43 #include <sys/resource.h>
56 #include <libzonecfg.h>
58 static void usage(void);
59 static int donice(int which
, id_t who
, int prio
, int increment
, char *who_s
);
60 static int parse_obsolete_options(int argc
, char **argv
);
61 static int name2id(char *);
65 #define RENICE_DEFAULT_PRIORITY 10
66 #define RENICE_PRIO_INCREMENT 1
67 #define RENICE_PRIO_ABSOLUTE 0
74 static type_t types
[] = {
75 { PRIO_PROCESS
, "pid" },
76 { PRIO_PGRP
, "pgid" },
78 { PRIO_USER
, "user" },
79 { PRIO_TASK
, "taskid" },
80 { PRIO_PROJECT
, "projid" },
81 { PRIO_PROJECT
, "project" },
82 { PRIO_GROUP
, "gid" },
83 { PRIO_GROUP
, "group" },
84 { PRIO_SESSION
, "sid" },
85 { PRIO_ZONE
, "zone" },
86 { PRIO_ZONE
, "zoneid" },
87 { PRIO_CONTRACT
, "ctid" },
92 * Change the priority (nice) of processes
93 * or groups of processes which are already
98 main(int argc
, char *argv
[])
102 int which
= PRIO_PROCESS
;
106 int incr
= RENICE_DEFAULT_PRIORITY
;
107 int prio_type
= RENICE_PRIO_INCREMENT
;
111 (void) setlocale(LC_ALL
, "");
112 #if !defined(TEXT_DOMAIN)
113 #define TEXT_DOMAIN "SYS_TEST"
115 (void) textdomain(TEXT_DOMAIN
);
121 * There is ambiguity in the renice options spec.
122 * If argv[1] is in the valid range of priority values then
123 * treat it as a priority. Otherwise, treat it as a pid.
126 if (isdigit(argv
[1][0])) {
127 if (strtol(argv
[1], (char **)NULL
, 10) > (PRIO_MAX
+1)) {
128 argc
--; /* renice pid ... */
130 prio_type
= RENICE_PRIO_INCREMENT
;
131 } else { /* renice priority ... */
132 exit(parse_obsolete_options(argc
, argv
));
134 } else if ((argv
[1][0] == '-' || argv
[1][0] == '+') &&
135 isdigit(argv
[1][1])) { /* renice priority ... */
137 exit(parse_obsolete_options(argc
, argv
));
139 } else { /* renice [-n increment] [-g|-p|-u] ID ... */
141 while ((c
= getopt(argc
, argv
, "n:gpui:")) != -1) {
144 incr
= strtol(optarg
, &end_ptr
, 10);
145 prio_type
= RENICE_PRIO_INCREMENT
;
146 if (*end_ptr
!= '\0')
154 which
= PRIO_PROCESS
;
162 which
= name2id(optarg
);
173 if (argc
== 0 || (optflag
> 1))
177 for (; argc
> 0; argc
--, argv
++) {
179 if (isdigit(argv
[0][0])) {
180 who
= strtol(*argv
, &end_ptr
, 10);
182 /* if a zone id, make sure it is valid */
183 if (who
>= 0 && end_ptr
!= *argv
&&
184 *end_ptr
== '\0' && (which
!= PRIO_ZONE
||
185 getzonenamebyid(who
, NULL
, 0) != -1) &&
186 (which
!= PRIO_CONTRACT
|| who
!= 0)) {
187 errs
+= donice(which
, who
, incr
, prio_type
,
195 if ((pwd
= getpwnam(*argv
)) != NULL
) {
197 errs
+= donice(which
, who
, incr
, prio_type
,
200 (void) fprintf(stderr
,
201 gettext("renice: unknown user: %s\n"),
207 if ((grp
= getgrnam(*argv
)) != NULL
) {
209 errs
+= donice(which
, who
, incr
, prio_type
,
212 (void) fprintf(stderr
,
213 gettext("renice: unknown group: %s\n"),
219 if ((who
= getprojidbyname(*argv
)) != (id_t
)-1) {
220 errs
+= donice(which
, who
, incr
, prio_type
,
223 (void) fprintf(stderr
,
224 gettext("renice: unknown project: %s\n"),
230 if (zone_get_id(*argv
, &who
) != 0) {
231 (void) fprintf(stderr
,
232 gettext("renice: unknown zone: %s\n"),
237 errs
+= donice(which
, who
, incr
, prio_type
, *argv
);
241 * In all other cases it is invalid id or name
243 (void) fprintf(stderr
,
244 gettext("renice: bad value: %s\n"), *argv
);
253 parse_obsolete_options(int argc
, char *argv
[])
255 int which
= PRIO_PROCESS
;
268 prio
= strtol(*argv
, &end_ptr
, 10);
269 if (*end_ptr
!= '\0') {
274 (void) fprintf(stderr
,
275 gettext("renice: nice value 20 rounded down to 19\n"));
281 for (; argc
> 0; argc
--, argv
++) {
282 if (strcmp(*argv
, "-g") == 0) {
286 if (strcmp(*argv
, "-u") == 0) {
290 if (strcmp(*argv
, "-p") == 0) {
291 which
= PRIO_PROCESS
;
294 if (which
== PRIO_USER
&& !isdigit(argv
[0][0])) {
295 struct passwd
*pwd
= getpwnam(*argv
);
298 (void) fprintf(stderr
,
299 gettext("renice: unknown user: %s\n"),
306 who
= strtol(*argv
, &end_ptr
, 10);
307 if ((who
< 0) || (*end_ptr
!= '\0')) {
308 (void) fprintf(stderr
,
309 gettext("renice: bad value: %s\n"), *argv
);
314 errs
+= donice(which
, who
, prio
, RENICE_PRIO_ABSOLUTE
, *argv
);
322 donice(int which
, id_t who
, int prio
, int increment
, char *who_s
)
326 oldprio
= getpriority(which
, who
);
328 if (oldprio
== -1 && errno
) {
329 (void) fprintf(stderr
, gettext("renice: %d:"), who
);
330 perror("getpriority");
335 prio
= oldprio
+ prio
;
337 if (setpriority(which
, who
, prio
) < 0) {
338 (void) fprintf(stderr
, gettext("renice: %s:"), who_s
);
339 if (errno
== EACCES
&& prio
< oldprio
)
340 (void) fprintf(stderr
, gettext(
341 " Cannot lower nice value.\n"));
343 perror("setpriority");
353 (void) fprintf(stderr
,
354 gettext("usage: renice [-n increment] [-i idtype] ID ...\n"));
355 (void) fprintf(stderr
,
356 gettext(" renice [-n increment] [-g | -p | -u] ID ...\n"));
357 (void) fprintf(stderr
,
358 gettext(" renice priority "
359 "[-p] pid ... [-g pgrp ...] [-p pid ...] [-u user ...]\n"));
360 (void) fprintf(stderr
,
361 gettext(" renice priority "
362 " -g pgrp ... [-g pgrp ...] [-p pid ...] [-u user ...]\n"));
363 (void) fprintf(stderr
,
364 gettext(" renice priority "
365 " -u user ... [-g pgrp ...] [-p pid ...] [-u user ...]\n"));
366 (void) fprintf(stderr
,
367 gettext(" where %d <= priority <= %d\n"), PRIO_MIN
, PRIO_MAX
);
374 type_t
*type
= types
;
376 while (type
->name
!= NULL
) {
377 if (strcmp(type
->name
, name
) == 0)
381 (void) fprintf(stderr
, gettext("renice: unknown id type: %s\n"), name
);