Annotation of src/usr.bin/renice/renice.c, Revision 1.17
1.17 ! millert 1: /* $OpenBSD: renice.c,v 1.16 2013/11/15 22:20:04 millert Exp $ */
1.2 deraadt 2:
1.1 deraadt 3: /*
1.17 ! millert 4: * Copyright (c) 2009, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
1.1 deraadt 5: *
1.13 millert 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.
1.1 deraadt 9: *
1.13 millert 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.
1.1 deraadt 17: */
18:
19: #include <sys/types.h>
20: #include <sys/time.h>
21: #include <sys/resource.h>
1.5 millert 22:
1.13 millert 23: #include <ctype.h>
24: #include <err.h>
25: #include <errno.h>
26: #include <limits.h>
27: #include <pwd.h>
1.1 deraadt 28: #include <stdio.h>
1.3 deraadt 29: #include <stdlib.h>
1.11 david 30: #include <string.h>
1.16 millert 31: #include <unistd.h>
1.13 millert 32:
1.17 ! millert 33: #define RENICE_NONE 0
! 34: #define RENICE_ABSOLUTE 1
! 35: #define RENICE_INCREMENT 2
! 36:
1.13 millert 37: struct renice_param {
38: int pri;
1.17 ! millert 39: short pri_type;
! 40: short id_type;
1.13 millert 41: id_t id;
42: };
1.1 deraadt 43:
1.8 millert 44: int main(int, char **);
1.13 millert 45: static int renice(struct renice_param *, struct renice_param *);
46: __dead void usage(void);
1.3 deraadt 47:
48: int
1.13 millert 49: main(int argc, char **argv)
1.1 deraadt 50: {
1.13 millert 51: struct renice_param *params, *p;
52: struct passwd *pw;
1.17 ! millert 53: int ch, id_type = PRIO_PROCESS;
! 54: int pri = 0, pri_type = RENICE_NONE;
1.13 millert 55: char *ep, *idstr;
56: const char *errstr;
1.1 deraadt 57:
1.13 millert 58: if (argc < 3)
1.5 millert 59: usage();
1.13 millert 60:
61: /* Allocate enough space for the worst case. */
1.17 ! millert 62: params = p = reallocarray(NULL, argc - 1, sizeof(*params));
1.13 millert 63: if (params == NULL)
64: err(1, NULL);
65:
66: /* Backwards compatibility: first arg may be priority. */
1.14 millert 67: if (isdigit((unsigned char)argv[1][0]) ||
1.17 ! millert 68: ((argv[1][0] == '+' || argv[1][0] == '-') &&
! 69: isdigit((unsigned char)argv[1][1]))) {
! 70: pri = (int)strtol(argv[1], &ep, 10);
! 71: if (*ep != '\0' || ep == argv[1]) {
! 72: warnx("invalid priority %s", argv[1]);
! 73: usage();
! 74: }
! 75: pri_type = RENICE_ABSOLUTE;
! 76: optind = 2;
1.13 millert 77: }
78:
79: /*
80: * Slightly tricky getopt() usage since it is legal to have
81: * option flags interleaved with arguments.
82: */
83: for (;;) {
84: if ((ch = getopt(argc, argv, "g:n:p:u:")) != -1) {
85: switch (ch) {
86: case 'g':
1.17 ! millert 87: id_type = PRIO_PGRP;
1.13 millert 88: idstr = optarg;
89: break;
90: case 'n':
1.17 ! millert 91: pri = (int)strtol(optarg, &ep, 10);
1.13 millert 92: if (*ep != '\0' || ep == optarg) {
93: warnx("invalid increment %s", optarg);
94: usage();
95: }
96:
97: /* Set priority for previous entries? */
1.17 ! millert 98: if (pri_type == RENICE_NONE) {
1.13 millert 99: struct renice_param *pp;
100: for (pp = params; pp != p; pp++) {
101: pp->pri = pri;
1.17 ! millert 102: pp->pri_type = RENICE_INCREMENT;
1.13 millert 103: }
104: }
1.17 ! millert 105: pri_type = RENICE_INCREMENT;
1.13 millert 106: continue;
107: case 'p':
1.17 ! millert 108: id_type = PRIO_PROCESS;
1.13 millert 109: idstr = optarg;
110: break;
111: case 'u':
1.17 ! millert 112: id_type = PRIO_USER;
1.13 millert 113: idstr = optarg;
114: break;
115: default:
116: usage();
117: break;
118: }
119: } else {
120: idstr = argv[optind++];
121: if (idstr == NULL)
122: break;
1.1 deraadt 123: }
1.17 ! millert 124: p->id_type = id_type;
1.13 millert 125: p->pri = pri;
1.17 ! millert 126: p->pri_type = pri_type;
! 127: if (id_type == PRIO_USER) {
1.13 millert 128: if ((pw = getpwnam(idstr)) == NULL) {
129: uid_t id = strtonum(idstr, 0, UID_MAX, &errstr);
130: if (!errstr)
131: pw = getpwuid(id);
132: }
133: if (pw == NULL) {
134: warnx("unknown user %s", idstr);
1.1 deraadt 135: continue;
136: }
1.13 millert 137: p->id = pw->pw_uid;
1.1 deraadt 138: } else {
1.13 millert 139: p->id = strtonum(idstr, 0, UINT_MAX, &errstr);
140: if (errstr) {
141: warnx("%s is %s", idstr, errstr);
1.1 deraadt 142: continue;
143: }
144: }
1.13 millert 145: p++;
1.1 deraadt 146: }
1.17 ! millert 147: if (pri_type == RENICE_NONE)
1.13 millert 148: usage();
149: exit(renice(params, p));
1.1 deraadt 150: }
151:
1.13 millert 152: static int
153: renice(struct renice_param *p, struct renice_param *end)
1.1 deraadt 154: {
1.17 ! millert 155: int new, old, errors = 0;
1.1 deraadt 156:
1.13 millert 157: for (; p < end; p++) {
158: errno = 0;
1.17 ! millert 159: old = getpriority(p->id_type, p->id);
1.13 millert 160: if (errno) {
161: warn("getpriority: %d", p->id);
162: errors++;
163: continue;
164: }
1.17 ! millert 165: if (p->pri_type == RENICE_INCREMENT)
! 166: p->pri += old;
! 167: new = p->pri > PRIO_MAX ? PRIO_MAX :
! 168: p->pri < PRIO_MIN ? PRIO_MIN : p->pri;
! 169: if (setpriority(p->id_type, p->id, new) == -1) {
1.13 millert 170: warn("setpriority: %d", p->id);
171: errors++;
172: continue;
173: }
174: printf("%d: old priority %d, new priority %d\n",
1.17 ! millert 175: p->id, old, new);
1.1 deraadt 176: }
1.13 millert 177: return (errors);
1.5 millert 178: }
179:
1.13 millert 180: __dead void
1.10 deraadt 181: usage(void)
1.5 millert 182: {
1.13 millert 183: fprintf(stderr, "usage: renice -n increment [[-g] pgrp ...] "
184: "[[-p] pid ...] [[-u] user ...]\n");
1.5 millert 185: exit(1);
1.1 deraadt 186: }