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