]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/renice/renice.c
Add 'contrib/unifdef/' from commit '0da44885831dc0a43c4ca6ff04a2430993cc0a80'
[FreeBSD/FreeBSD.git] / usr.bin / renice / renice.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1983, 1989, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #ifndef lint
33 static const char copyright[] =
34 "@(#) Copyright (c) 1983, 1989, 1993\n\
35         The Regents of the University of California.  All rights reserved.\n";
36 #endif /* not lint */
37
38 #if 0
39 #ifndef lint
40 static char sccsid[] = "@(#)renice.c    8.1 (Berkeley) 6/9/93";
41 #endif /* not lint */
42 #endif
43
44 #include <sys/cdefs.h>
45 #include <sys/types.h>
46 #include <sys/time.h>
47 #include <sys/resource.h>
48
49 #include <err.h>
50 #include <errno.h>
51 #include <limits.h>
52 #include <pwd.h>
53 #include <stdbool.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57
58 static int      donice(int, int, int, bool);
59 static int      getnum(const char *, const char *, int *);
60 static void     usage(void);
61
62 /*
63  * Change the priority (nice) of processes
64  * or groups of processes which are already
65  * running.
66  */
67 int
68 main(int argc, char *argv[])
69 {
70         struct passwd *pwd;
71         bool havedelim = false, haveprio = false, incr = false;
72         int errs = 0, prio = 0, who = 0, which = PRIO_PROCESS;
73
74         for (argc--, argv++; argc > 0; argc--, argv++) {
75                 if (!havedelim) {
76                         /* can occur at any time prior to delimiter */
77                         if (strcmp(*argv, "-g") == 0) {
78                                 which = PRIO_PGRP;
79                                 continue;
80                         }
81                         if (strcmp(*argv, "-u") == 0) {
82                                 which = PRIO_USER;
83                                 continue;
84                         }
85                         if (strcmp(*argv, "-p") == 0) {
86                                 which = PRIO_PROCESS;
87                                 continue;
88                         }
89                         if (strcmp(*argv, "--") == 0) {
90                                 havedelim = true;
91                                 continue;
92                         }
93                         if (strcmp(*argv, "-n") == 0) {
94                                 /* may occur only once, prior to priority */
95                                 if (haveprio || incr || argc < 2)
96                                         usage();
97                                 incr = true;
98                                 (void)argc--, argv++;
99                                 /* fall through to priority */
100                         }
101                 }
102                 if (!haveprio) {
103                         /* must occur exactly once, prior to target */
104                         if (getnum("priority", *argv, &prio))
105                                 return (1);
106                         haveprio = true;
107                         continue;
108                 }
109                 if (which == PRIO_USER) {
110                         if ((pwd = getpwnam(*argv)) != NULL)
111                                 who = pwd->pw_uid;
112                         else if (getnum("uid", *argv, &who)) {
113                                 errs++;
114                                 continue;
115                         } else if (who < 0) {
116                                 warnx("%s: bad value", *argv);
117                                 errs++;
118                                 continue;
119                         }
120                 } else {
121                         if (getnum("pid", *argv, &who)) {
122                                 errs++;
123                                 continue;
124                         }
125                         if (who < 0) {
126                                 warnx("%s: bad value", *argv);
127                                 errs++;
128                                 continue;
129                         }
130                 }
131                 errs += donice(which, who, prio, incr);
132         }
133         if (!haveprio)
134                 usage();
135         exit(errs != 0);
136 }
137
138 static int
139 donice(int which, int who, int prio, bool incr)
140 {
141         int oldprio;
142
143         errno = 0;
144         oldprio = getpriority(which, who);
145         if (oldprio == -1 && errno) {
146                 warn("%d: getpriority", who);
147                 return (1);
148         }
149         if (incr)
150                 prio = oldprio + prio;
151         if (prio > PRIO_MAX)
152                 prio = PRIO_MAX;
153         if (prio < PRIO_MIN)
154                 prio = PRIO_MIN;
155         if (setpriority(which, who, prio) < 0) {
156                 warn("%d: setpriority", who);
157                 return (1);
158         }
159         fprintf(stderr, "%d: old priority %d, new priority %d\n", who,
160             oldprio, prio);
161         return (0);
162 }
163
164 static int
165 getnum(const char *com, const char *str, int *val)
166 {
167         long v;
168         char *ep;
169
170         errno = 0;
171         v = strtol(str, &ep, 10);
172         if (v < INT_MIN || v > INT_MAX || errno == ERANGE) {
173                 warnx("%s argument %s is out of range.", com, str);
174                 return (1);
175         }
176         if (ep == str || *ep != '\0' || errno != 0) {
177                 warnx("%s argument %s is invalid.", com, str);
178                 return (1);
179         }
180
181         *val = (int)v;
182         return (0);
183 }
184
185 static void
186 usage(void)
187 {
188         fprintf(stderr, "%s\n%s\n",
189 "usage: renice priority [[-p] pid ...] [[-g] pgrp ...] [[-u] user ...]",
190 "       renice -n increment [[-p] pid ...] [[-g] pgrp ...] [[-u] user ...]");
191         exit(1);
192 }