1 |
|
|
/* $OpenBSD: renice.c,v 1.20 2016/09/19 20:20:38 bluhm Exp $ */ |
2 |
|
|
|
3 |
|
|
/* |
4 |
|
|
* Copyright (c) 2009, 2015 Todd C. Miller <Todd.Miller@courtesan.com> |
5 |
|
|
* |
6 |
|
|
* Permission to use, copy, modify, and distribute this software for any |
7 |
|
|
* purpose with or without fee is hereby granted, provided that the above |
8 |
|
|
* copyright notice and this permission notice appear in all copies. |
9 |
|
|
* |
10 |
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 |
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 |
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 |
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 |
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 |
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 |
|
|
*/ |
18 |
|
|
|
19 |
|
|
#include <sys/types.h> |
20 |
|
|
#include <sys/time.h> |
21 |
|
|
#include <sys/resource.h> |
22 |
|
|
|
23 |
|
|
#include <ctype.h> |
24 |
|
|
#include <err.h> |
25 |
|
|
#include <errno.h> |
26 |
|
|
#include <limits.h> |
27 |
|
|
#include <pwd.h> |
28 |
|
|
#include <stdio.h> |
29 |
|
|
#include <stdlib.h> |
30 |
|
|
#include <string.h> |
31 |
|
|
#include <unistd.h> |
32 |
|
|
|
33 |
|
|
#define RENICE_NONE 0 |
34 |
|
|
#define RENICE_ABSOLUTE 1 |
35 |
|
|
#define RENICE_INCREMENT 2 |
36 |
|
|
|
37 |
|
|
struct renice_param { |
38 |
|
|
int pri; |
39 |
|
|
short pri_type; |
40 |
|
|
short id_type; |
41 |
|
|
id_t id; |
42 |
|
|
}; |
43 |
|
|
|
44 |
|
|
int main(int, char **); |
45 |
|
|
static int renice(struct renice_param *, struct renice_param *); |
46 |
|
|
__dead void usage(void); |
47 |
|
|
|
48 |
|
|
int |
49 |
|
|
main(int argc, char **argv) |
50 |
|
|
{ |
51 |
|
|
struct renice_param *params, *p; |
52 |
|
|
struct passwd *pw; |
53 |
|
|
int ch, id_type = PRIO_PROCESS; |
54 |
|
|
int pri = 0, pri_type = RENICE_NONE; |
55 |
|
|
char *ep, *idstr; |
56 |
|
|
const char *errstr; |
57 |
|
|
|
58 |
|
|
if (pledge("stdio getpw proc flock rpath cpath wpath", NULL) == -1) |
59 |
|
|
err(1, "pledge"); |
60 |
|
|
|
61 |
|
|
if (argc < 3) |
62 |
|
|
usage(); |
63 |
|
|
|
64 |
|
|
/* Allocate enough space for the worst case. */ |
65 |
|
|
params = p = reallocarray(NULL, argc - 1, sizeof(*params)); |
66 |
|
|
if (params == NULL) |
67 |
|
|
err(1, NULL); |
68 |
|
|
|
69 |
|
|
/* Backwards compatibility: first arg may be priority. */ |
70 |
|
|
if (isdigit((unsigned char)argv[1][0]) || |
71 |
|
|
((argv[1][0] == '+' || argv[1][0] == '-') && |
72 |
|
|
isdigit((unsigned char)argv[1][1]))) { |
73 |
|
|
pri = (int)strtol(argv[1], &ep, 10); |
74 |
|
|
if (*ep != '\0' || ep == argv[1]) { |
75 |
|
|
warnx("invalid priority %s", argv[1]); |
76 |
|
|
usage(); |
77 |
|
|
} |
78 |
|
|
pri_type = RENICE_ABSOLUTE; |
79 |
|
|
optind = 2; |
80 |
|
|
} |
81 |
|
|
|
82 |
|
|
/* |
83 |
|
|
* Slightly tricky getopt() usage since it is legal to have |
84 |
|
|
* option flags interleaved with arguments. |
85 |
|
|
*/ |
86 |
|
|
for (;;) { |
87 |
|
|
if ((ch = getopt(argc, argv, "g:n:p:u:")) != -1) { |
88 |
|
|
switch (ch) { |
89 |
|
|
case 'g': |
90 |
|
|
id_type = PRIO_PGRP; |
91 |
|
|
idstr = optarg; |
92 |
|
|
break; |
93 |
|
|
case 'n': |
94 |
|
|
pri = (int)strtol(optarg, &ep, 10); |
95 |
|
|
if (*ep != '\0' || ep == optarg) { |
96 |
|
|
warnx("invalid increment %s", optarg); |
97 |
|
|
usage(); |
98 |
|
|
} |
99 |
|
|
|
100 |
|
|
/* Set priority for previous entries? */ |
101 |
|
|
if (pri_type == RENICE_NONE) { |
102 |
|
|
struct renice_param *pp; |
103 |
|
|
for (pp = params; pp != p; pp++) { |
104 |
|
|
pp->pri = pri; |
105 |
|
|
pp->pri_type = RENICE_INCREMENT; |
106 |
|
|
} |
107 |
|
|
} |
108 |
|
|
pri_type = RENICE_INCREMENT; |
109 |
|
|
continue; |
110 |
|
|
case 'p': |
111 |
|
|
id_type = PRIO_PROCESS; |
112 |
|
|
idstr = optarg; |
113 |
|
|
break; |
114 |
|
|
case 'u': |
115 |
|
|
id_type = PRIO_USER; |
116 |
|
|
idstr = optarg; |
117 |
|
|
break; |
118 |
|
|
default: |
119 |
|
|
usage(); |
120 |
|
|
break; |
121 |
|
|
} |
122 |
|
|
} else { |
123 |
|
|
idstr = argv[optind++]; |
124 |
|
|
if (idstr == NULL) |
125 |
|
|
break; |
126 |
|
|
} |
127 |
|
|
p->id_type = id_type; |
128 |
|
|
p->pri = pri; |
129 |
|
|
p->pri_type = pri_type; |
130 |
|
|
if (id_type == PRIO_USER) { |
131 |
|
|
if ((pw = getpwnam(idstr)) == NULL) { |
132 |
|
|
uid_t id = strtonum(idstr, 0, UID_MAX, &errstr); |
133 |
|
|
if (!errstr) |
134 |
|
|
pw = getpwuid(id); |
135 |
|
|
} |
136 |
|
|
if (pw == NULL) { |
137 |
|
|
warnx("unknown user %s", idstr); |
138 |
|
|
continue; |
139 |
|
|
} |
140 |
|
|
p->id = pw->pw_uid; |
141 |
|
|
} else { |
142 |
|
|
p->id = strtonum(idstr, 0, UINT_MAX, &errstr); |
143 |
|
|
if (errstr) { |
144 |
|
|
warnx("%s is %s", idstr, errstr); |
145 |
|
|
continue; |
146 |
|
|
} |
147 |
|
|
} |
148 |
|
|
p++; |
149 |
|
|
} |
150 |
|
|
if (pri_type == RENICE_NONE) |
151 |
|
|
usage(); |
152 |
|
|
return(renice(params, p)); |
153 |
|
|
} |
154 |
|
|
|
155 |
|
|
static int |
156 |
|
|
renice(struct renice_param *p, struct renice_param *end) |
157 |
|
|
{ |
158 |
|
|
int new, old, errors = 0; |
159 |
|
|
|
160 |
|
|
for (; p < end; p++) { |
161 |
|
|
errno = 0; |
162 |
|
|
old = getpriority(p->id_type, p->id); |
163 |
|
|
if (errno) { |
164 |
|
|
warn("getpriority: %d", p->id); |
165 |
|
|
errors++; |
166 |
|
|
continue; |
167 |
|
|
} |
168 |
|
|
if (p->pri_type == RENICE_INCREMENT) |
169 |
|
|
p->pri += old; |
170 |
|
|
new = p->pri > PRIO_MAX ? PRIO_MAX : |
171 |
|
|
p->pri < PRIO_MIN ? PRIO_MIN : p->pri; |
172 |
|
|
if (setpriority(p->id_type, p->id, new) == -1) { |
173 |
|
|
warn("setpriority: %d", p->id); |
174 |
|
|
errors++; |
175 |
|
|
continue; |
176 |
|
|
} |
177 |
|
|
printf("%d: old priority %d, new priority %d\n", |
178 |
|
|
p->id, old, new); |
179 |
|
|
} |
180 |
|
|
return (errors); |
181 |
|
|
} |
182 |
|
|
|
183 |
|
|
__dead void |
184 |
|
|
usage(void) |
185 |
|
|
{ |
186 |
|
|
fprintf(stderr, "usage: renice [-n] increment [-gpu] id\n"); |
187 |
|
|
exit(1); |
188 |
|
|
} |